diff --git a/.circleci/config.yml b/.circleci/config.yml
index 3b747af461727b9b3760091c51feb4c46795fe7d..cf279ad5aa4405498bc060f77afed52ce545e0a0 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -205,6 +205,19 @@ jobs:
           command: ./node_modules/.bin/yamllint `find resources -name '*.yaml'`
           no_output_timeout: 2m
 
+  verify-i18n-files:
+    executor: node
+    steps:
+      - attach-workspace
+      - restore-fe-deps-cache
+      - run:
+          name: Install gettext
+          command: sudo apt-get install gettext
+      - run:
+          name: Verify i18n .po files
+          command: ./bin/i18n/build-translation-resources
+          no_output_timeout: 2m
+
 
 ########################################################################################################################
 #                                                       BACKEND                                                        #
@@ -467,6 +480,11 @@ workflows:
           requires:
             - checkout
 
+      - verify-i18n-files:
+          requires:
+            - checkout
+            - fe-deps
+
       - be-deps:
           requires:
             - checkout
@@ -660,6 +678,7 @@ workflows:
       - deploy-master:
           requires:
             - yaml-linter
+            - verify-i18n-files
 
             - be-linter-bikeshed
             - be-linter-docstring-checker
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 58275417d725fd412eb57913f40c1efe11e4c6c0..5e4ea422703a7b104ce2a823ab8273844ba06be6 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,39 +1,4 @@
-------
-Before filing an issue we'd appreciate it if you could take a moment to ensure
-there isn't already an open issue or pull-request.
------
 
-If there's an existing issue, please add a :+1: reaction to the description of
-the issue. One way we prioritize issues is by the number of :+1: reactions on
-their descriptions. Please DO NOT add `+1` or :+1: comments.
+Please use the issue chooser, when creating a new issue:
 
-### Security Disclosure
-
-Security is very important to us. If discover any issue regarding security, please disclose the information responsibly by sending an email to security@metabase.com and not by creating a GitHub issue.
-
-### Database support
-
-For requests for new database drivers, please include the name
-of the database and the version. Additionally, giving us a sense of how and what
-you use it for, and other high-level details about the database, can help us get
-a better picture of what would need to done to support it.
-
-### Feature requests and proposals
-We're excited to hear how we can make Metabase better. Please add as much detail
-as you can on your use case.
-
-### Bugs
-If you're filing an issue about a bug please include as much information
-as you can including the following.
-
-- Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, IE 10)
-- Your operating system: (e.x. OS X 10, Windows XP, etc)
-- Your databases: (e.x. MySQL, Postgres, MongoDB, …)
-- Metabase version: (e.x. 0.19.3)
-- Metabase hosting environment: (e.x. Mac app, Elastic Beanstalk, Docker, Heroku, Linux/Ubuntu 12)
-- Metabase internal database: (e.x. H2 (default), MySQL, Postgres)
-
-- *Repeatable steps to reproduce the issue*
-
-Thanks for being part of the Metabase project!
--------
+https://github.com/metabase/metabase/issues/new/choose
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index d3dbcdbfd15dbad69a8ef5f6ef056c87baf3810f..2af2d5f478df7ff13e0e72dd3005f8589ceb03bf 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -11,7 +11,7 @@ assignees: ''
 A clear and concise description of what the bug is.
 
 **Logs**
-Please include javascript console and server logs around the time this bug occured. For information about how to get these, consult our [bug troubleshooting guide](https://metabase.com/docs/latest/troubleshooting-guide/bugs.html)
+Please include javascript console and server logs around the time this bug occurred. For information about how to get these, consult our [bug troubleshooting guide](https://metabase.com/docs/latest/troubleshooting-guide/bugs.html)
 
 **To Reproduce**
 Steps to reproduce the behavior:
@@ -27,22 +27,16 @@ A clear and concise description of what you expected to happen.
 If applicable, add screenshots to help explain your problem.
 
 **Information about your Metabase Installation:**
-- Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, IE 10)
-
-- Your operating system: (e.x. OS X 10, Windows XP, etc)
-
+- Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, Safari 11.1, …)
+- Your operating system: (e.x. OS X 10.10, Windows 10.1809, Ubuntu 16.04, …)
 - Your databases: (e.x. MySQL, Postgres, MongoDB, …)
-
 - Metabase version: (e.x. 0.19.3)
-
-- Metabase hosting environment: (e.x. Mac app, Elastic Beanstalk, Docker, Heroku, Linux/Ubuntu 12)
-
-- Metabase internal database: (e.x. H2 (default), MySQL, Postgres)
+- Metabase hosting environment: (e.x. Mac app, Elastic Beanstalk, Docker, Heroku, Jar-file on Ubuntu, …)
+- Metabase internal database: (e.x. H2 (default), Postgres or MySQL)
 
 **Severity**
 How severe an issue is this bug to you? Is this annoying, blocking some users, blocking an upgrade or blocking your usage of Metabase entirely?
-
-Note: the more honest and specific you are here the more we will take you seriously. 
+Note: the more honest and specific you are here the more we will take you seriously.
 
 **Additional context**
 Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/questions-and-help.md b/.github/ISSUE_TEMPLATE/questions-and-help.md
index e59d0747dffb6fea064b1a6f57b442bf1b19053f..d9a54d50e4075a164ca52f8c5b9b94acc020cc05 100644
--- a/.github/ISSUE_TEMPLATE/questions-and-help.md
+++ b/.github/ISSUE_TEMPLATE/questions-and-help.md
@@ -7,6 +7,9 @@ assignees: ''
 
 ---
 
-This issue tracker is intended to collect bug reports and feature requests.
+For help with installation and setup, information on how specific features work, or general questions about Metabase, please use our discussion forum:
 
-For help with installation, information on how features work, or questions about specific features of Metabase, please create a thread on our [discussion forum](https://discourse.metabase.com). Any issues open for help requests will be closed to keep from clogging up the issue tracker.
+https://discourse.metabase.com
+
+The Github issue tracker is intended to collect bug reports and feature requests.
+Any issues open for help requests will be closed to keep from clogging up the issue tracker.
diff --git a/bin/aws-eb-docker/.ebextensions/metabase_config/metabase-setup.sh b/bin/aws-eb-docker/.ebextensions/metabase_config/metabase-setup.sh
index 87dae77d45136a7e0e03ee612637a729ca10f065..093165e9aa3aeb9e7c5ad48da2fe71fabda51562 100755
--- a/bin/aws-eb-docker/.ebextensions/metabase_config/metabase-setup.sh
+++ b/bin/aws-eb-docker/.ebextensions/metabase_config/metabase-setup.sh
@@ -67,6 +67,11 @@ server {
         proxy_set_header    Host                $host;
         proxy_set_header    X-Real-IP            $remote_addr;
         proxy_set_header    X-Forwarded-For        $proxy_add_x_forwarded_for;
+        proxy_connect_timeout 600;
+        proxy_send_timeout 600;
+        proxy_read_timeout 600;
+        send_timeout 600;
+
     }
 
 
@@ -83,6 +88,10 @@ server {
         proxy_set_header    Host                $host;
         proxy_set_header    X-Real-IP            $remote_addr;
         proxy_set_header    X-Forwarded-For        $proxy_add_x_forwarded_for;
+        proxy_connect_timeout 600;
+        proxy_send_timeout 600;
+        proxy_read_timeout 600;
+        send_timeout 600;
     }
 }
 EOF
diff --git a/bin/version b/bin/version
index 99a0cb566a4dbda3c8cf1078affde7ecc7c50bca..55ee2a26333d29713de31a39013a3b8cd4b12e73 100755
--- a/bin/version
+++ b/bin/version
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-VERSION="v0.33.0"
+VERSION="v0.33.1"
 
 # dynamically pull more interesting stuff from latest git commit
 HASH=$(git show-ref --head --hash=7 head)            # first 7 letters of hash should be enough; that's what GitHub uses
diff --git a/docs/administration-guide/01-managing-databases.md b/docs/administration-guide/01-managing-databases.md
index 76954c820a6b007a56ad7c3a2ca47925fe670206..3df9809ee53cc0eb884d0e0fbd99950057f382af 100644
--- a/docs/administration-guide/01-managing-databases.md
+++ b/docs/administration-guide/01-managing-databases.md
@@ -53,6 +53,10 @@ To add a database, you'll need its connection information.
    - Database Name - Find this under "Configuration Details"
    - Password - Ask your database administrator for the password.
 
+#### Errors When Connecting
+
+If you're experiencing errors when connecting to your database, check our [troubleshooting guide](../troubleshooting-guide/datawarehouse.md) for help.
+
 ### Secure Socket Layer (SSL)
 
 Metabase automatically tries to connect to databases with and without SSL. If it is possible to connect to your database with a SSL connection, Metabase will make that the default setting for your database. You can always change this setting later if you prefer to connect without this layer of security, but we highly recommend keeping SSL turned on to keep your data secure.
@@ -73,9 +77,9 @@ Metabase maintains its own information about the various tables and fields in ea
 
 Syncing can be set to hourly, or daily at a specific time. Syncing can't be turned off completely, otherwise Metabase wouldn't work.
 
-If you'd like to sync your database manually at any time, click on it from the Databases list in the admin panel and click on the Sync button on the right side of the screen:
+If you'd like to sync your database manually at any time, click on it from the Databases list in the admin panel and click on the Sync database schema now button on the right side of the screen:
 
-![Database connection](images/DatabaseConnection.png)
+![Database Manual Sync](images/DatabaseManualSync.png)
 
 #### Query auto-running settings
 
@@ -97,9 +101,7 @@ If for some reason you need to flush out the cached field values for your databa
 
 ##### Re-scanning a single table or field
 
-To re-scan a specific table, go to the Data Model section of the Admin Panel, select the table from the list, and click the gear icon in the top right of the page. Similarly, to do this for just a specific field, on the same Data Model page, find the field you want and click the gear icon on the far right of the field's name and options:
-
-![Field options][images/field-options.png]
+To re-scan a specific table, go to the Data Model section of the Admin Panel, select the table from the list, and click the gear icon in the top right of the page. Similarly, to do this for just a specific field, on the same Data Model page, find the field you want and click the gear icon on the far right of the field's name and options.
 
 On either the table settings or field settings page, you'll see these options:
 
@@ -109,7 +111,7 @@ On either the table settings or field settings page, you'll see these options:
 
 To delete a database from Metabase, click on **Remove this database** from the database detail screen.
 
-![databaseconnection](images/DatabaseConnection.png)
+![Database Manual Sync](images/DatabaseManualSync.png)
 
 You can also delete a database from the database list: hover over the row with the database you want to remove and click the **Delete** button that appears.
 
diff --git a/docs/administration-guide/04-managing-users.md b/docs/administration-guide/04-managing-users.md
index ee0f2e8e0fbcb9a7e89168566d853d0bc100a3a0..4f6da69f64e786c3e9d68b5e45e6df48a350cd58 100644
--- a/docs/administration-guide/04-managing-users.md
+++ b/docs/administration-guide/04-managing-users.md
@@ -24,7 +24,9 @@ To reactivate a deactivated user, click on the Deactivated tab at the top of the
 You can edit a user’s name and email address by clicking the three dots icon and choosing **Edit Details**. Note: be careful when changing a user’s email address, because *this will change the address they’ll use to log in to Metabase*.
 
 ### Resetting a user’s password
-A user can always reset their password using the forgot password link on the login screen, but if you want to do this for them, just click the three dots icon and choose Reset Password. If you haven’t configured your email settings yet, you’ll be given a temporary password that you’ll have to share with that user. Otherwise, they’ll receive a password reset email.
+If you've already [configured your email settings](02-setting-up-email.md), a user can reset their password using the forgot password link on the login screen. If you have not yet configured your email settings, they will see a message telling them to ask an admin to reset their password for them. 
+
+To reset a password for a user, just click the three dots icon and choose Reset Password. If you haven’t [configured your email settings](02-setting-up-email.md) yet, you’ll be given a temporary password that you’ll have to share with that user. Otherwise, they’ll receive a password reset email.
 
 ### Changing a user’s role
 Right now, the only special role a user can have is Admin. The only difference is that Admins can access the Admin Panel and make changes there, and can set [permissions on collections](06-collections.md).
diff --git a/docs/administration-guide/images/DatabaseManualSync.png b/docs/administration-guide/images/DatabaseManualSync.png
new file mode 100644
index 0000000000000000000000000000000000000000..b19cb05ffab455e78f8693b418089e44125fdc44
Binary files /dev/null and b/docs/administration-guide/images/DatabaseManualSync.png differ
diff --git a/docs/enterprise-guide/audit.md b/docs/enterprise-guide/audit.md
new file mode 100644
index 0000000000000000000000000000000000000000..fb4a3fe1d37cb416db3787b5cf82f3a6d7b338de
--- /dev/null
+++ b/docs/enterprise-guide/audit.md
@@ -0,0 +1,65 @@
+## Audit Logs
+
+As an administrator of Metabase, you already know the importance of using data to understand your users. With the Audit tool, you can use Metabase to understand your Metabase user's usage. It's, well, meta! 
+
+Access the tool by clicking the gear icon in the upper right and then clicking Audit in the top navigation. There's a lot of data available, not only about your people, but also about your questions, dashboard, databases and more! We'll walk you through each of the sections below.
+
+### People
+
+Use the People section to gain a better understanding of how your end-users are interacting with Metabase. You'll want to pay attention to the Overview Tab, especially when you first launch Metabase at your organization - it will give you data around how many active and newly created users you have each day. Further down the page, you'll see charts showing you which of your users are most engaged. Use these charts to find your power users!
+
+![Team Members](/images/audit-team.png)
+
+The Team members panel has a view other options for viewing your team's usage data. The All members tab will give you a list of your team members, and stats about their activity, such as when they were last active.
+
+The Audit log tab will display, in chronological order, each query, who viewed it, and when. Note that if the user did not save their query, the Name will be listed as Ad-hoc. Each query name can be clicked to view more details about your user's interactions with it, including a full revision history. You will also be able to view the query in Metabase. Note that this link will always show the latest version of the query - use the revision history to see changes over time.
+
+
+#### Drilling In
+
+Throughout the People section, names can be clicked to access the profile of a specific user’s activity. This profile includes:
+
+* Dashboard views
+* Query views
+* Downloads
+
+![Team Members](/images/audit-teammember.png)
+
+### Data
+
+The Data section focuses on your databases, schemas and tables, and is divided into corresponding sections. Look here if you're trying to uncover queries and schemas that need optimization.  Each section provides visualizations around the use and speed of querying against your databases, schemas or tables. You will also be able to view lists of stats about all of your databases, schemas and tables.
+
+![Data](/images/audit-data.png)
+
+### Items
+The Items section focuses on questions, dashboards and downloads, and is divided into corresponding sections. Use these pages to gain a better understanding of what your users are interacting with.
+
+#### Questions
+
+The Questions section will show you your most popular queries, as well as your slowest queries. If queries you think are important aren't appearing on your most popular queries list, you may want to make sure your team is focusing on the right things. 
+
+If important queries are appearing on the list of slowest queries, you will want to look at optimizing them. One option is to adjust your [caching settings](../../14-caching.html), but there are plenty of other options as well. To help you determine if your optimization efforts are heading in the right direction, use the Query views and speed per day visualization at the bottom of the page.
+
+![Items](/images/audit-questions.png)
+
+A list of all of your questions is available as well, and you can see various data points about each question at a glance, such as number of views and cache TTL.
+
+#### Drilling In
+
+You can also click on any question to drill into a more detailed profile showing:
+
+* View activity
+* Revision History
+* A full audit log of who viewed the question, and when
+
+#### Dashboards
+
+The Dashboards section is another great way to understand what your users who are dashboard-focused are looking at, and to make sure they're having a smooth experience. If you notice that a popular dashboard has a high average question loading time, you can investigate further using the Questions section outlined above.
+
+![Items](/images/audit-dashboards.png)
+
+A list of all of your dashboards is available as well, and you can see various data points about each dashboard at a glance, such as number of views and average question execution time.
+
+#### Downloads
+
+Use the Downloads section to understand which of your users are downloading (or exporting data) and the size (number of rows) of the downloads they're performing. This section contains some visualizations, as well as a list of all of all downloads.
\ No newline at end of file
diff --git a/docs/enterprise-guide/images/audit-dashboards.png b/docs/enterprise-guide/images/audit-dashboards.png
new file mode 100644
index 0000000000000000000000000000000000000000..c0fabf7698a6da624fb418e1d6eb99d2fdd28e7f
Binary files /dev/null and b/docs/enterprise-guide/images/audit-dashboards.png differ
diff --git a/docs/enterprise-guide/images/audit-data.png b/docs/enterprise-guide/images/audit-data.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b1024ac9a69fe4d30aa181fb23ba0c569ede9c5
Binary files /dev/null and b/docs/enterprise-guide/images/audit-data.png differ
diff --git a/docs/enterprise-guide/images/audit-questions.png b/docs/enterprise-guide/images/audit-questions.png
new file mode 100644
index 0000000000000000000000000000000000000000..25954b947056c199692e2bf293447fe10d515bf6
Binary files /dev/null and b/docs/enterprise-guide/images/audit-questions.png differ
diff --git a/docs/enterprise-guide/images/audit-team.png b/docs/enterprise-guide/images/audit-team.png
new file mode 100644
index 0000000000000000000000000000000000000000..97059255dc017f2b67c39f82d20f643af3e6319c
Binary files /dev/null and b/docs/enterprise-guide/images/audit-team.png differ
diff --git a/docs/enterprise-guide/images/audit-teammember.png b/docs/enterprise-guide/images/audit-teammember.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c64388df6e17111a80e249fd41cc82695ec9705
Binary files /dev/null and b/docs/enterprise-guide/images/audit-teammember.png differ
diff --git a/docs/enterprise-guide/start.md b/docs/enterprise-guide/start.md
index fd6dabcd8b75b75cc320e04f09683fa0a047d4aa..40545b7010658e92272a955d440e7c67014c9a78 100644
--- a/docs/enterprise-guide/start.md
+++ b/docs/enterprise-guide/start.md
@@ -10,3 +10,4 @@ The Enterprise Edition of Metabase provides added functionality and solutions fo
 * [Customizing how Metabase looks with white labeling](whitelabeling.md)
 * [Customizing drill-through for charts and tables](customizing-drill-through.md)
 * [Copying contents of one Metabase instance to another (serialization)](serialization.md)
+* [Using the audit logs](audit.md)
diff --git a/docs/faq/start.md b/docs/faq/start.md
index b39e0bf21bb2dc3e7feb93a4ab17401be7bfe9e6..60782e37c30fd51f50eaf745a5b2c01ba8055ccd 100644
--- a/docs/faq/start.md
+++ b/docs/faq/start.md
@@ -4,25 +4,26 @@ Here is a list of some frequently asked questions about Metabase.
 
 ## General Questions
 
-* [How do I ask for help?](general/how-do-i-ask-for-help.md)
-* [What if I find a bug?](general/what-if-i-find-a-bug.md)
-* [Can I request a new feature?](general/can-i-request-a-new-feature.md)
-* [Does Metabase do X?](general/does-metabase-do-x.md)
-* [Does Metabase have access to my data?](general/does-metabase-have-access-to-my-companys-data.md)
-* [Do we need a Data Processing Agreement with Metabase to comply with GDPR?](general/do-we-need-a-data-processing-agreement.md)
+- [How do I ask for help?](general/how-do-i-ask-for-help.md)
+- [What if I find a bug?](general/what-if-i-find-a-bug.md)
+- [Can I request a new feature?](general/can-i-request-a-new-feature.md)
+- [Does Metabase do X?](general/does-metabase-do-x.md)
+- [Does Metabase have access to my data?](general/does-metabase-have-access-to-my-companys-data.md)
+- [Do we need a Data Processing Agreement with Metabase to comply with GDPR?](general/do-we-need-a-data-processing-agreement.md)
 
 ## Set-up and Admin Questions
 
-* [Which databases does Metabase support?](setup/which-databases-does-metabase-support.md)
-* [I'm having trouble running Metabase.](setup/i-am-having-trouble-running-metabase.md)
-* [What's H2?](setup/what-is-h2.md)
-* [When should I migrate H2 to MySQL or Postgres?](setup/when-should-i-migrate-h2.md)
-* [How do I integrate Metabase and our single-sign on (SSO) solution?](setup/how-do-i-integrate-with-sso.md)
+- [Which databases does Metabase support?](setup/which-databases-does-metabase-support.md)
+- [I'm having trouble running Metabase.](setup/i-am-having-trouble-running-metabase.md)
+- [What's H2?](setup/what-is-h2.md)
+- [When should I migrate H2 to MySQL or Postgres?](setup/when-should-i-migrate-h2.md)
+- [How do I integrate Metabase and our single-sign on (SSO) solution?](setup/how-do-i-integrate-with-sso.md)
 
 ## Using Metabase
 
-* [How do I ask questions about my data?](using-metabase/how-do-i-ask-questions.md)
-* [I'm not getting the email notifications I expect to!](using-metabase/i-am-not-getting-email-notifications.md)
-* [How do I answer questions about data that lives in multiple databases?](using-metabase/how-do-i-answer-questions-when-data-is-in-multiple-databases.md)
-* [How do I answer questions where I need to join tables together?](using-metabase/how-do-i-answer-questions-with-joins.md)
-* [I’m trying to ask a question, but it looks like I can’t access some of the data I need.](using-metabase/cant-access-data-i-need.md)
+- [How do I reset my password?](using-metabase/how-do-i-reset-my-password.md)
+- [How do I ask questions about my data?](using-metabase/how-do-i-ask-questions.md)
+- [I'm not getting the email notifications I expect to!](using-metabase/i-am-not-getting-email-notifications.md)
+- [How do I answer questions about data that lives in multiple databases?](using-metabase/how-do-i-answer-questions-when-data-is-in-multiple-databases.md)
+- [How do I answer questions where I need to join tables together?](using-metabase/how-do-i-answer-questions-with-joins.md)
+- [I’m trying to ask a question, but it looks like I can’t access some of the data I need.](using-metabase/cant-access-data-i-need.md)
diff --git a/docs/faq/using-metabase/how-do-i-reset-my-password.md b/docs/faq/using-metabase/how-do-i-reset-my-password.md
new file mode 100644
index 0000000000000000000000000000000000000000..f6d37258b0fec1aa0f503563f66bc031e2b30cc2
--- /dev/null
+++ b/docs/faq/using-metabase/how-do-i-reset-my-password.md
@@ -0,0 +1,3 @@
+# How do I reset my password?
+
+If you're having trouble logging in due to a forgotten password, click the `I seem to have forgotten my password` button in the lower right of the log-in screen. If your Metabase administrator has already [configured your email settings](02-setting-up-email.md), you will be able to generate a Reset Password email. If email has not been configured, you will need to contact them to perform a password reset.
\ No newline at end of file
diff --git a/docs/operations-guide/running-metabase-on-debian.md b/docs/operations-guide/running-metabase-on-debian.md
index 4178d8b451a598307f507fb4b30516a7ad76c01d..0bbdf55b6f6f07cf6ff6bf0307f3f19dc614fe9b 100644
--- a/docs/operations-guide/running-metabase-on-debian.md
+++ b/docs/operations-guide/running-metabase-on-debian.md
@@ -13,105 +13,65 @@ The core assumption in this guide:
 * You will use environment variables to configure your Metabase instance
 * You have `sudo` access on your server
 
-### Create a Metabase Service
-
-Every service needs a script that tells `systemd` how to manage it, and what capabilities it supports. Services are typically registered at `etc/init.d/<service-name>`. So, a Metabase service should live at `/etc/init.d/metabase`.
+### Create an unprivileged user to run Metabase and give him acces to app and logs
 
-#### The Metabase service file
+For security reasons we want to have Metabase run as an unprivileged user. We will call the user simply `metabase`. Further we will create the files we will need later for logging and configuration of Metabase, and apply the correct security settings for our unprivileged user.
 
-Create the `/etc/init.d/metabase` service file and open it in your editor:
-
-    $ sudo touch /etc/init.d/metabase
-    $ sudo <your-editor> /etc/init.d/metabase
-
-In `/etc/init.d/metabase`, replace configurable items (they look like `<some-var-name>`) with values sensible for your system. The Metabase script below has extra comments to help you know what everything is for.
-
-
-    #!/bin/sh
-    # /etc/init.d/metabase
-    ### BEGIN INIT INFO
-    # Provides:          Metabase
-    # Required-Start:    $local_fs $network $named $time $syslog
-    # Required-Stop:     $local_fs $network $named $time $syslog
-    # Default-Start:     2 3 4 5
-    # Default-Stop:      0 1 6
-    # Description:       Metabase analytics and intelligence platform
-    ### END INIT INFO
-
-    # where is the Metabase jar located?
-    METABASE=</your/path/to/>metabase.jar
-
-    # where will our environment variables be stored?
-    METABASE_CONFIG=/etc/default/metabase
-
-    # which (unprivileged) user should we run Metabase as?
-    RUNAS=<your_deploy_user>
-
-    # where should we store the pid/log files?
-    PIDFILE=/var/run/metabase.pid
-    LOGFILE=/var/log/metabase.log
-
-    start() {
-      # ensure we only run 1 Metabase instance
-      if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then
-        echo 'Metabase already running' >&2
-        return 1
-      fi
-      echo 'Starting Metabase...' >&2
-      # execute the Metabase jar and send output to our log
-      local CMD="nohup java -jar \"$METABASE\" &> \"$LOGFILE\" & echo \$!"
-      # load Metabase config before we start so our env vars are available
-      . "$METABASE_CONFIG"
-      # run our Metabase cmd as unprivileged user
-      su -c "$CMD" $RUNAS > "$PIDFILE"
-      echo 'Metabase started.' >&2
-    }
+    $ sudo groupadd -r metabase
+    $ sudo useradd -r -s /bin/false -g metabase metabase
+    $ sudo chown -R metabase:metabase </your/path/to/metabase/directory>
+    $ sudo touch /var/log/metabase.log
+    $ sudo chown metabase:metabase /var/log/metabase.log
+    $ sudo touch /etc/default/metabase
+    $ sudo chmod 640 /etc/default/metabase
 
-    stop() {
-      # ensure Metabase is running
-      if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
-        echo 'Metabase not running' >&2
-        return 1
-      fi
-      echo 'Stopping Metabase ...' >&2
-      # send Metabase TERM signal
-      kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
-      echo 'Metabase stopped.' >&2
-    }
+### Create a Metabase Service
 
-    uninstall() {
-      echo -n "Are you really sure you want to uninstall Metabase? That cannot be undone. [yes|No] "
-      local SURE
-      read SURE
-      if [ "$SURE" = "yes" ]; then
-        stop
-        rm -f "$PIDFILE"
-        rm -f "$METABASE_CONFIG"
-        # keep logfile around
-        echo "Notice: log file is not be removed: '$LOGFILE'" >&2
-        update-rc.d -f metabase remove
-        rm -fv "$0"
-      fi
-    }
+Every service needs a script that tells `systemd` how to manage it, and what capabilities it supports. Services are typically registered at `/etc/systemd/system/<servicename>`. So, a Metabase service should live at `/etc/systemd/system/metabase.service`.
 
-    case "$1" in
-      start)
-        start
-        ;;
-      stop)
-        stop
-        ;;
-      uninstall)
-        uninstall
-        ;;
-      restart)
-        stop
-        start
-        ;;
-      *)
-        echo "Usage: $0 {start|stop|restart|uninstall}"
-    esac
+#### The Metabase service file
 
+Create the `/etc/systemd/system/metabase.service` service file and open it in your editor:
+
+    $ sudo touch /etc/systemd/system/metabase.service
+    $ sudo <your-editor> /etc/systemd/system/metabase.service
+
+In `/etc/systemd/system/metabase.service`, replace configurable items (they look like `<some-var-name>`) with values sensible for your system. The Metabase script below has extra comments to help you know what everything is for.
+
+    [Unit]
+    Description=Metabase server
+    After=syslog.target
+    After=network.target
+   
+    [Service]
+    WorkingDirectory=</your/path/to/metabase/directory/>
+    ExecStart=/usr/bin/java -jar </your/path/to/metabase/directory/>metabase.jar
+    EnvironmentFile=/etc/default/metabase
+    User=metabase
+    Type=simple
+    StandardOutput=syslog
+    StandardError=syslog
+    SyslogIdentifier=metabase
+    SuccessExitStatus=143
+    TimeoutStopSec=120
+    Restart=always
+   
+    [Install]
+    WantedBy=multi-user.target
+    
+### Create syslog conf
+
+Next we need to create a syslog conf to make sure systemd is able to handle the logs properly.
+
+    $ sudo touch /etc/rsyslog.d/metabase.conf
+    $ sudo <your-editor> /etc/rsyslog.d/metabase.conf
+    
+    if $programname == 'metabase' then /var/log/metabase.log
+    & stop
+    
+Restart the syslog service to load the new config.
+
+    $ sudo systemctl restart rsyslog.service
 
 ### Environment Variables for Metabase
 
@@ -119,27 +79,24 @@ Environment variables provide a good way to customize and configure your Metabas
 
 #### The Metabase config file
 
-Create your `/etc/default/metabase` environment config file and open it in your editor:
+Open your `/etc/default/metabase` environment config file in your editor:
 
-    $ sudo touch /etc/default/metabase
     $ sudo <your-editor> /etc/default/metabase
 
 In `/etc/default/metabase`, replace configurable items (they look like `<some-var-name>`) with values sensible for your system. Some Metabase configs have available options, some of which are shown below, separated by `|` symbols:
 
 
-    #!/bin/sh
-    # /etc/default/metabase
-    export MB_PASSWORD_COMPLEXITY=<weak|normal|strong>
-    export MB_PASSWORD_LENGTH=<10>
-    export MB_JETTY_HOST=<0.0.0.0>
-    export MB_JETTY_PORT=<12345>
-    export MB_DB_TYPE=<postgres|mysql|h2>
-    export MB_DB_DBNAME=<your_metabase_db_name>
-    export MB_DB_PORT=<5432>
-    export MB_DB_USER=<your_metabase_db_user>
-    export MB_DB_PASS=<ssshhhh>
-    export MB_DB_HOST=<localhost>
-    export MB_EMOJI_IN_LOGS=<true|false>
+    MB_PASSWORD_COMPLEXITY=<weak|normal|strong>
+    MB_PASSWORD_LENGTH=<10>
+    MB_JETTY_HOST=<0.0.0.0>
+    MB_JETTY_PORT=<12345>
+    MB_DB_TYPE=<postgres|mysql|h2>
+    MB_DB_DBNAME=<your_metabase_db_name>
+    MB_DB_PORT=<5432>
+    MB_DB_USER=<your_metabase_db_user>
+    MB_DB_PASS=<ssshhhh>
+    MB_DB_HOST=<localhost>
+    MB_EMOJI_IN_LOGS=<true|false>
     # any other env vars you want available to Metabase
 
 ### Final Steps
@@ -171,23 +128,20 @@ Getting into too much detail about configuring `nginx` is well outside the scope
 
 Now, it's time to register our Metabase service with `systemd` so it will start up at system boot. We'll also ensure our log file is created and owned by the unprivileged user our service runs the `metabase.jar` as.
 
-    # ensure our metabase script is executable
-    $ sudo chmod +x /etc/init.d/metabase
+    $ sudo systemctl daemon-reload
+    $ sudo systemctl start metabase.service
+    $ sudo systemctl status metabase.service
 
-    # create the log file we declared in /etc/init.d/metabase
-    $ sudo touch /var/log/metabase.log
+Once we are ok here, enable the service to startup during boot.
 
-    # ensure unprivileged deploy user owns log (or it won't be able to write)
-    $ sudo chown <your_deploy_user>:<your_deploy_user> /var/log/metabase.log
+    $ sudo systemctl enable metabase.service
 
-    # add to default services
-    $ sudo update-rc.d metabase defaults
 
 #### That's it!
 
 Now, whenever you need to start, stop, or restart Metabase, all you need to do is:
 
-    $ sudo service metabase start
-    $ sudo service metabase stop
-    $ sudo service metabase restart
+    $ sudo systemctl start metabase.service
+    $ sudo systemctl stop metabase.service
+    $ sudo systemctl restart metabase.service
 
diff --git a/docs/operations-guide/running-the-metabase-jar-file.md b/docs/operations-guide/running-the-metabase-jar-file.md
index f5951d582b8b5bae7522dee1c774ac715dbc3897..81e9c20616546bf7af0d161849f909ea16096a62 100644
--- a/docs/operations-guide/running-the-metabase-jar-file.md
+++ b/docs/operations-guide/running-the-metabase-jar-file.md
@@ -40,9 +40,9 @@ It's that simple.  This will start the Metabase application using all of the def
     2015-10-14 22:17:51,049 [INFO ] org.eclipse.jetty.server.ServerConnector :: Started ServerConnector@30aba609{HTTP/1.1}{localhost:3000}
     2015-10-14 22:17:51,050 [INFO ] org.eclipse.jetty.server.Server :: Started @35910ms
 
-At this point your ready to go!  You can access your new Metabase server on port 3000, most likely at [localhost:3000](http://localhost:3000)
+At this point you're ready to go!  You can access your new Metabase server on port 3000, most likely at [localhost:3000](http://localhost:3000)
 
-You can use another port than 3000 by setting the `MB_JETTY_PORT` environment variable before running the jar
+You can use another port than 3000 by setting the `MB_JETTY_PORT` environment variable before running the jar.
 
 Note that in the default configuration Metabase will use a local H2 database for storing all its own application data.  This is meant for simple evaluations or personal use, so if you want to run Metabase for a team we recommend you upgrade to a more robust SQL server such as Postgres.  See below for details on how to do that.
 
diff --git a/docs/troubleshooting-guide/loggingin.md b/docs/troubleshooting-guide/loggingin.md
index 5f8f0b49b54319ee8df19b9b02e91e91e2047eff..632481d0ad69c506a47ad487206a17f6e4106efe 100644
--- a/docs/troubleshooting-guide/loggingin.md
+++ b/docs/troubleshooting-guide/loggingin.md
@@ -17,6 +17,10 @@ Also open up your server logs, and see if there are any errors related to authen
 #### How to fix this:
 Remove the old token from the Google Auth SSO tab in the Admin Panel and create a new one. If the root cause was an invalid auth token, this should fix the problem.
 
+### Forgotten Password
+
+[This FAQ](../faq/how-do-i-reset-my-password.md) will tell you what to do in the event of a forgotten password.
+
 
 
 ## Helpful tidbits
diff --git a/docs/troubleshooting-guide/timezones.md b/docs/troubleshooting-guide/timezones.md
index 0280c6c27d4bc78b5693d82654002e9c7b704d83..8f01e794f839437b1ebc6e97672c0e894a99ecbc 100644
--- a/docs/troubleshooting-guide/timezones.md
+++ b/docs/troubleshooting-guide/timezones.md
@@ -40,7 +40,7 @@ Now that you have the time zone adjustment, look at the list of time zone questi
 
 For example, let's say have a PST server time zone, and a GMT reporting time zone. If you had to manually go back 9 hours to get correct numbers, that suggests that the conversion is not happening for some reason -- this suggests you are using timestamps without a time zone.
 
-You can see a number of common problems below. If none of them apply, please [open a bug report](www.github.com/metabase/metabase/issues/new) with the above information (time zones, and the results of the second troubleshooting process) as well as your Metabase, OS, and web browser versions.
+You can see a number of common problems below. If none of them apply, please [open a bug report](https://github.com/metabase/metabase/issues/new/choose) with the above information (time zones, and the results of the second troubleshooting process) as well as your Metabase, OS, and web browser versions.
 
 ## Specific Problems:
 
diff --git a/frontend/src/metabase/App.jsx b/frontend/src/metabase/App.jsx
index 32d4d78077e622a3a0f3de6694c5fcd22ff5b434..527e4e7ee1e2fe9b91f586862f30339e540e6095 100644
--- a/frontend/src/metabase/App.jsx
+++ b/frontend/src/metabase/App.jsx
@@ -3,7 +3,7 @@
 import React, { Component } from "react";
 import { connect } from "react-redux";
 import ScrollToTop from "metabase/hoc/ScrollToTop";
-import Navbar from "metabase/nav/containers/Navbar.jsx";
+import Navbar from "metabase/nav/containers/Navbar";
 
 import UndoListing from "metabase/containers/UndoListing";
 
diff --git a/frontend/src/metabase/admin/databases/components/CreatedDatabaseModal.jsx b/frontend/src/metabase/admin/databases/components/CreatedDatabaseModal.jsx
index 566636698568b0d8f4100765d3a3a555cc49f7ca..d1f683e8d024560b497c62908adbeb5a0f33cc59 100644
--- a/frontend/src/metabase/admin/databases/components/CreatedDatabaseModal.jsx
+++ b/frontend/src/metabase/admin/databases/components/CreatedDatabaseModal.jsx
@@ -6,7 +6,7 @@ import { t } from "ttag";
 import MetabaseSettings from "metabase/lib/settings";
 
 import Button from "metabase/components/Button";
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalContent from "metabase/components/ModalContent";
 
 type Props = {
   databaseId: number,
diff --git a/frontend/src/metabase/admin/databases/components/DatabaseEditForms.jsx b/frontend/src/metabase/admin/databases/components/DatabaseEditForms.jsx
index 8cbf4a565bc3ea1bc527d71841ed4d86a90677fa..04c5001cf2a54a8ab1bd801a4521588ce0091487 100644
--- a/frontend/src/metabase/admin/databases/components/DatabaseEditForms.jsx
+++ b/frontend/src/metabase/admin/databases/components/DatabaseEditForms.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
-import DatabaseDetailsForm from "metabase/components/DatabaseDetailsForm.jsx";
+import DatabaseDetailsForm from "metabase/components/DatabaseDetailsForm";
 import { t } from "ttag";
 
 export default class DatabaseEditForms extends Component {
diff --git a/frontend/src/metabase/admin/databases/components/DatabaseSchedulingForm.jsx b/frontend/src/metabase/admin/databases/components/DatabaseSchedulingForm.jsx
index 6be60668a1bd5729af918fae92672c7d02394f1e..af9654bae0a29b1da42a8380bc5298eb3acd84f0 100644
--- a/frontend/src/metabase/admin/databases/components/DatabaseSchedulingForm.jsx
+++ b/frontend/src/metabase/admin/databases/components/DatabaseSchedulingForm.jsx
@@ -9,7 +9,7 @@ import SchedulePicker from "metabase/components/SchedulePicker";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export const SyncOption = ({ selected, name, children, select }) => (
   <div
@@ -22,7 +22,7 @@ export const SyncOption = ({ selected, name, children, select }) => (
         width: 18,
         height: 18,
         borderWidth: 2,
-        borderColor: selected ? colors["brand"] : colors["text-light"],
+        borderColor: selected ? color("brand") : color("text-light"),
         borderStyle: "solid",
       }}
     >
@@ -32,7 +32,7 @@ export const SyncOption = ({ selected, name, children, select }) => (
           style={{
             width: 8,
             height: 8,
-            backgroundColor: selected ? colors["brand"] : colors["text-light"],
+            backgroundColor: selected ? color("brand") : color("text-light"),
           }}
         />
       )}
diff --git a/frontend/src/metabase/admin/databases/components/DeleteDatabaseModal.jsx b/frontend/src/metabase/admin/databases/components/DeleteDatabaseModal.jsx
index d0e72281b835ed06f09359e4090ebfac421f9c05..471f31402ac66f1d060ebf7c27132568053064fd 100644
--- a/frontend/src/metabase/admin/databases/components/DeleteDatabaseModal.jsx
+++ b/frontend/src/metabase/admin/databases/components/DeleteDatabaseModal.jsx
@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
 import { t } from "ttag";
 
 import Button from "metabase/components/Button";
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalContent from "metabase/components/ModalContent";
 
 export default class DeleteDatabaseModal extends Component {
   constructor(props, context) {
diff --git a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx
index f047ef7a2bd769b364b15547957197fb92441fed..ed65466c73547a9c72c6d8dfc48def1f12bfd2fd 100644
--- a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx
+++ b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx
@@ -7,13 +7,13 @@ import title from "metabase/hoc/Title";
 import { t } from "ttag";
 
 import MetabaseSettings from "metabase/lib/settings";
-import DeleteDatabaseModal from "../components/DeleteDatabaseModal.jsx";
-import DatabaseEditForms from "../components/DatabaseEditForms.jsx";
+import DeleteDatabaseModal from "../components/DeleteDatabaseModal";
+import DatabaseEditForms from "../components/DatabaseEditForms";
 import DatabaseSchedulingForm from "../components/DatabaseSchedulingForm";
-import ActionButton from "metabase/components/ActionButton.jsx";
-import Breadcrumbs from "metabase/components/Breadcrumbs.jsx";
-import Radio from "metabase/components/Radio.jsx";
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
+import ActionButton from "metabase/components/ActionButton";
+import Breadcrumbs from "metabase/components/Breadcrumbs";
+import Radio from "metabase/components/Radio";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
 
 import {
   getEditingDatabase,
diff --git a/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx b/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx
index 372956fa7c6e681cadd8a3a6433adfe405ce611c..3d255df31a377765abc91ef764daa1bea2ef1e29 100644
--- a/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx
+++ b/frontend/src/metabase/admin/databases/containers/DatabaseListApp.jsx
@@ -9,12 +9,12 @@ import { t } from "ttag";
 import cx from "classnames";
 import MetabaseSettings from "metabase/lib/settings";
 
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
 import FormMessage from "metabase/components/form/FormMessage";
 
-import CreatedDatabaseModal from "../components/CreatedDatabaseModal.jsx";
-import DeleteDatabaseModal from "../components/DeleteDatabaseModal.jsx";
+import CreatedDatabaseModal from "../components/CreatedDatabaseModal";
+import DeleteDatabaseModal from "../components/DeleteDatabaseModal";
 
 import Database from "metabase/entities/databases";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/ObjectActionSelect.jsx b/frontend/src/metabase/admin/datamodel/components/ObjectActionSelect.jsx
index 03d3eb83d13f1513b20d9fd9991060d38c2c1bcc..96d54afea25cfcf3ba47bf982a1ccc27b15a9b9f 100644
--- a/frontend/src/metabase/admin/datamodel/components/ObjectActionSelect.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/ObjectActionSelect.jsx
@@ -2,11 +2,11 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Link } from "react-router";
 
-import Icon from "metabase/components/Icon.jsx";
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
+import Icon from "metabase/components/Icon";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
 import { t } from "ttag";
-import ObjectRetireModal from "./ObjectRetireModal.jsx";
+import ObjectRetireModal from "./ObjectRetireModal";
 
 import { capitalize } from "metabase/lib/formatting";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/ObjectRetireModal.jsx b/frontend/src/metabase/admin/datamodel/components/ObjectRetireModal.jsx
index 63e929c66fd0095d6c1be58b9b357b5ac07abc60..bee4564245ce5631c567fe5434ea1e2e6a8e5810 100644
--- a/frontend/src/metabase/admin/datamodel/components/ObjectRetireModal.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/ObjectRetireModal.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 import ReactDOM from "react-dom";
 
-import ActionButton from "metabase/components/ActionButton.jsx";
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ActionButton from "metabase/components/ActionButton";
+import ModalContent from "metabase/components/ModalContent";
 import { t } from "ttag";
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx b/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx
index 09367576675cbad31126c51904a705b4b1163d82..cbd99ae08d82583ecb6944598c1c4f74ea009b13 100644
--- a/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import GuiQueryEditor from "metabase/query_builder/components/GuiQueryEditor.jsx";
+import GuiQueryEditor from "metabase/query_builder/components/GuiQueryEditor";
 import { t } from "ttag";
 import * as Urls from "metabase/lib/urls";
 
@@ -57,15 +57,7 @@ export default class PartialQueryBuilder extends Component {
     }).query();
 
     const previewCard = {
-      dataset_query: {
-        ...datasetQuery,
-        query: {
-          aggregation: ["rows"],
-          breakout: [],
-          filter: [],
-          ...datasetQuery.query,
-        },
-      },
+      dataset_query: datasetQuery,
     };
     const previewUrl = Urls.question(null, previewCard);
 
diff --git a/frontend/src/metabase/admin/datamodel/components/UpdateCachedFieldValues.jsx b/frontend/src/metabase/admin/datamodel/components/UpdateCachedFieldValues.jsx
index 272ed82f91b1fe42c825c2f0eedd4c1b007359f5..3c624998553662cffdf6a1133b6c41134d13f77c 100644
--- a/frontend/src/metabase/admin/datamodel/components/UpdateCachedFieldValues.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/UpdateCachedFieldValues.jsx
@@ -2,7 +2,7 @@ import React from "react";
 
 import { t } from "ttag";
 
-import ActionButton from "metabase/components/ActionButton.jsx";
+import ActionButton from "metabase/components/ActionButton";
 
 export default class UpdateCachedFieldValues extends React.Component {
   render() {
diff --git a/frontend/src/metabase/admin/datamodel/components/database/ColumnItem.jsx b/frontend/src/metabase/admin/datamodel/components/database/ColumnItem.jsx
index 9dd28f2a1d3b5e2526e4b751bb4c4da1f81cd8b9..2c3438adf54560971104dcfd04c3bf5e602ade90 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/ColumnItem.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/ColumnItem.jsx
@@ -2,8 +2,8 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Link, withRouter } from "react-router";
 
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
-import Select, { Option } from "metabase/components/Select.jsx";
+import InputBlurChange from "metabase/components/InputBlurChange";
+import Select, { Option } from "metabase/components/Select";
 import Icon from "metabase/components/Icon";
 import { t } from "ttag";
 import * as MetabaseCore from "metabase/lib/core";
diff --git a/frontend/src/metabase/admin/datamodel/components/database/ColumnsList.jsx b/frontend/src/metabase/admin/datamodel/components/database/ColumnsList.jsx
index 62763d4a27ef5372848dff3bd31f020cc1f157b6..4c10806f7ec60b688a233a76c6ad8311e0cf4aed 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/ColumnsList.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/ColumnsList.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import ColumnItem from "./ColumnItem.jsx";
+import ColumnItem from "./ColumnItem";
 
 export default class ColumnsList extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetadataHeader.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetadataHeader.jsx
index 2f39d34d19ed3bdb51040afc26289726778b101e..12d58b0a88f665604fede6245cae05db01711541 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/MetadataHeader.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/MetadataHeader.jsx
@@ -2,11 +2,11 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Link, withRouter } from "react-router";
 import { t } from "ttag";
-import SaveStatus from "metabase/components/SaveStatus.jsx";
-import Toggle from "metabase/components/Toggle.jsx";
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import ColumnarSelector from "metabase/components/ColumnarSelector.jsx";
-import Icon from "metabase/components/Icon.jsx";
+import SaveStatus from "metabase/components/SaveStatus";
+import Toggle from "metabase/components/Toggle";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import ColumnarSelector from "metabase/components/ColumnarSelector";
+import Icon from "metabase/components/Icon";
 import Databases from "metabase/entities/databases";
 
 @withRouter
diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx
index 3b64300ac9a96d35a1686a6c14af47a4b9cbe54d..8cc488974a82e3f05fbaf9f2802afc170c3d06fd 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx
@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 import { t, ngettext, msgid } from "ttag";
 
 import _ from "underscore";
diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetadataTable.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetadataTable.jsx
index eb175bd54daf017facffb19e9655107446c46074..727f90e5e95fe5f35dc3d8939c70069554c15348 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/MetadataTable.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/MetadataTable.jsx
@@ -1,11 +1,11 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import MetricsList from "./MetricsList.jsx";
-import ColumnsList from "./ColumnsList.jsx";
-import SegmentsList from "./SegmentsList.jsx";
+import MetricsList from "./MetricsList";
+import ColumnsList from "./ColumnsList";
+import SegmentsList from "./SegmentsList";
 import { t } from "ttag";
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
+import InputBlurChange from "metabase/components/InputBlurChange";
 import Databases from "metabase/entities/databases";
 import Tables from "metabase/entities/tables";
 import withTableMetadataLoaded from "metabase/admin/datamodel/withTableMetadataLoaded";
diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx
index 9567e13e5ec528f720fa026c6bf68890b93c1fc0..0b4111f387946879ec6b2a37b375b918d0545a90 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 import { t, ngettext, msgid } from "ttag";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetadataTablePicker.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetadataTablePicker.jsx
index 8ad5296c73ef4a0a501b6e7cc07addebb8d2dc61..05be829c1d00f259b0c1f3db9ecc2348ad4b52c9 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/MetadataTablePicker.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/MetadataTablePicker.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import MetadataTableList from "./MetadataTableList.jsx";
-import MetadataSchemaList from "./MetadataSchemaList.jsx";
+import MetadataTableList from "./MetadataTableList";
+import MetadataSchemaList from "./MetadataSchemaList";
 
 import Tables from "metabase/entities/tables";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetricItem.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetricItem.jsx
index 9bafb2ba22b77c0cbe4c1a307f40af3a42ff1f8b..493d2d994ff67fc640b3d0ab7ffa417c02f7d9d0 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/MetricItem.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/MetricItem.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import ObjectActionSelect from "../ObjectActionSelect.jsx";
+import ObjectActionSelect from "../ObjectActionSelect";
 
 import * as Q_DEPRECATED from "metabase/lib/query";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetricsList.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetricsList.jsx
index 4f2c9a760af4cf8de158344ddba2afd1c02390c3..fe6860f79f1eeccb5ccda908bfb97b1b7b63a883 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/MetricsList.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/MetricsList.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Link } from "react-router";
 import { t } from "ttag";
-import MetricItem from "./MetricItem.jsx";
+import MetricItem from "./MetricItem";
 
 export default class MetricsList extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/admin/datamodel/components/database/SegmentItem.jsx b/frontend/src/metabase/admin/datamodel/components/database/SegmentItem.jsx
index 6b4832445bf302bb7ee552515f6a6b1265c85d2f..3fbf1c6ab4e1d310c5c0017a18750ab0918f0b05 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/SegmentItem.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/SegmentItem.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import ObjectActionSelect from "../ObjectActionSelect.jsx";
+import ObjectActionSelect from "../ObjectActionSelect";
 
 import * as Q_DEPRECATED from "metabase/lib/query";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/database/SegmentsList.jsx b/frontend/src/metabase/admin/datamodel/components/database/SegmentsList.jsx
index b02aaad820a56eaa57ca0c767ab89cb386168b05..552e280f55b3f8590591dc8fcb7a08c8e627639a 100644
--- a/frontend/src/metabase/admin/datamodel/components/database/SegmentsList.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/database/SegmentsList.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Link } from "react-router";
 import { t } from "ttag";
-import SegmentItem from "./SegmentItem.jsx";
+import SegmentItem from "./SegmentItem";
 
 export default class SegmentsList extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/admin/datamodel/components/revisions/QueryDiff.jsx b/frontend/src/metabase/admin/datamodel/components/revisions/QueryDiff.jsx
index 11dd6bd6df3f06f0614741c4d2653b5146ce7c73..3bf2eef36d9615a86f9b5f4befeac204c22f0b15 100644
--- a/frontend/src/metabase/admin/datamodel/components/revisions/QueryDiff.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/revisions/QueryDiff.jsx
@@ -1,10 +1,10 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import FilterList from "metabase/query_builder/components/FilterList.jsx";
-import AggregationWidget from "metabase/query_builder/components/AggregationWidget.jsx";
+import FilterList from "metabase/query_builder/components/FilterList";
+import AggregationWidget from "metabase/query_builder/components/AggregationWidget";
 
 import * as Query from "metabase/lib/query/query";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/revisions/Revision.jsx b/frontend/src/metabase/admin/datamodel/components/revisions/Revision.jsx
index 20aa1f7e567a948d173ca9284f24d37bb96a97c8..d0698fd93442ee6485f65faec84f2c415afa388d 100644
--- a/frontend/src/metabase/admin/datamodel/components/revisions/Revision.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/revisions/Revision.jsx
@@ -1,9 +1,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import RevisionDiff from "./RevisionDiff.jsx";
+import RevisionDiff from "./RevisionDiff";
 import { t } from "ttag";
-import UserAvatar from "metabase/components/UserAvatar.jsx";
+import UserAvatar from "metabase/components/UserAvatar";
 
 import moment from "moment";
 
diff --git a/frontend/src/metabase/admin/datamodel/components/revisions/RevisionDiff.jsx b/frontend/src/metabase/admin/datamodel/components/revisions/RevisionDiff.jsx
index 0574a0a9325c6fe9b868fdc5580d3f723136151a..4e2b03cf07b5881e6dd458f5ca6508a82c0072c1 100644
--- a/frontend/src/metabase/admin/datamodel/components/revisions/RevisionDiff.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/revisions/RevisionDiff.jsx
@@ -1,10 +1,10 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import TextDiff from "./TextDiff.jsx";
-import QueryDiff from "./QueryDiff.jsx";
+import TextDiff from "./TextDiff";
+import QueryDiff from "./QueryDiff";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 export default class RevisionDiff extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/admin/datamodel/components/revisions/RevisionHistory.jsx b/frontend/src/metabase/admin/datamodel/components/revisions/RevisionHistory.jsx
index 457bbe7196281eea4cc056b60ae38de1eb336405..59f3ea014656c91246054ba3e3f8f8d1229291bc 100644
--- a/frontend/src/metabase/admin/datamodel/components/revisions/RevisionHistory.jsx
+++ b/frontend/src/metabase/admin/datamodel/components/revisions/RevisionHistory.jsx
@@ -1,10 +1,10 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Revision from "./Revision.jsx";
+import Revision from "./Revision";
 import { t } from "ttag";
-import Breadcrumbs from "metabase/components/Breadcrumbs.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import Breadcrumbs from "metabase/components/Breadcrumbs";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import Tables from "metabase/entities/tables";
 
 import { assignUserColors } from "metabase/lib/formatting";
diff --git a/frontend/src/metabase/admin/datamodel/containers/FieldApp.jsx b/frontend/src/metabase/admin/datamodel/containers/FieldApp.jsx
index eb0c7f8b91d0d6a925f0647cda2ef89e4cf2c180..66d559604b12bf474c31ac89475981f999e45567 100644
--- a/frontend/src/metabase/admin/datamodel/containers/FieldApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/FieldApp.jsx
@@ -22,11 +22,8 @@ import SaveStatus from "metabase/components/SaveStatus";
 import Breadcrumbs from "metabase/components/Breadcrumbs";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import AdminLayout from "metabase/components/AdminLayout.jsx";
-import {
-  LeftNavPane,
-  LeftNavPaneItem,
-} from "metabase/components/LeftNavPane.jsx";
+import AdminLayout from "metabase/components/AdminLayout";
+import { LeftNavPane, LeftNavPaneItem } from "metabase/components/LeftNavPane";
 import Section, { SectionHeader } from "../components/Section";
 import SelectSeparator from "../components/SelectSeparator";
 
@@ -47,7 +44,7 @@ import { rescanFieldValues, discardFieldValues } from "../field";
 // LIB
 import Metadata from "metabase-lib/lib/metadata/Metadata";
 import { has_field_values_options } from "metabase/lib/core";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import { getGlobalSettingsForColumn } from "metabase/visualizations/lib/settings/column";
 import { isCurrency } from "metabase/lib/schema_metadata";
 
@@ -392,7 +389,7 @@ export const BackButton = ({
   <Link
     to={`/admin/datamodel/database/${databaseId}/table/${tableId}`}
     className="circle text-white p2 flex align-center justify-center inline"
-    style={{ backgroundColor: colors["bg-dark"] }}
+    style={{ backgroundColor: color("bg-dark") }}
   >
     <Icon name="arrow_back" />
   </Link>
diff --git a/frontend/src/metabase/admin/datamodel/containers/MetadataEditorApp.jsx b/frontend/src/metabase/admin/datamodel/containers/MetadataEditorApp.jsx
index 6599ed65e4ee50927f030ca7386a2cc23c704ccd..4cf2b35b8565464c66eae37bee565b28315ff2ed 100644
--- a/frontend/src/metabase/admin/datamodel/containers/MetadataEditorApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/MetadataEditorApp.jsx
@@ -6,11 +6,11 @@ import { push } from "react-router-redux";
 import { t } from "ttag";
 import MetabaseAnalytics from "metabase/lib/analytics";
 
-import AdminEmptyText from "metabase/components/AdminEmptyText.jsx";
-import MetadataHeader from "../components/database/MetadataHeader.jsx";
-import MetadataTablePicker from "../components/database/MetadataTablePicker.jsx";
-import MetadataTable from "../components/database/MetadataTable.jsx";
-import MetadataSchema from "../components/database/MetadataSchema.jsx";
+import AdminEmptyText from "metabase/components/AdminEmptyText";
+import MetadataHeader from "../components/database/MetadataHeader";
+import MetadataTablePicker from "../components/database/MetadataTablePicker";
+import MetadataTable from "../components/database/MetadataTable";
+import MetadataSchema from "../components/database/MetadataSchema";
 import {
   metrics as Metrics,
   segments as Segments,
diff --git a/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx b/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx
index 676f98d985d8dbc994992d001ed8e3b891d0abdd..ae887c13d7b154f40f96d92aa12aa954a90382a3 100644
--- a/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx
@@ -10,7 +10,7 @@ import Tables from "metabase/entities/tables";
 import { updatePreviewSummary } from "../datamodel";
 import { getPreviewSummary } from "../selectors";
 import withTableMetadataLoaded from "../withTableMetadataLoaded";
-import MetricForm from "./MetricForm.jsx";
+import MetricForm from "./MetricForm";
 
 const mapDispatchToProps = {
   updatePreviewSummary,
diff --git a/frontend/src/metabase/admin/datamodel/containers/MetricForm.jsx b/frontend/src/metabase/admin/datamodel/containers/MetricForm.jsx
index 9a8c5f73a19932eb570e0959ca5e6a274b5dfc18..724224b9b826c9811820e62c31e00b42cb2aa6b6 100644
--- a/frontend/src/metabase/admin/datamodel/containers/MetricForm.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/MetricForm.jsx
@@ -1,11 +1,11 @@
 import React, { Component } from "react";
 import { Link } from "react-router";
 
-import FormLabel from "../components/FormLabel.jsx";
-import FormInput from "../components/FormInput.jsx";
-import FormTextArea from "../components/FormTextArea.jsx";
-import FieldSet from "metabase/components/FieldSet.jsx";
-import PartialQueryBuilder from "../components/PartialQueryBuilder.jsx";
+import FormLabel from "../components/FormLabel";
+import FormInput from "../components/FormInput";
+import FormTextArea from "../components/FormTextArea";
+import FieldSet from "metabase/components/FieldSet";
+import PartialQueryBuilder from "../components/PartialQueryBuilder";
 import { t } from "ttag";
 import { formatValue } from "metabase/lib/formatting";
 
diff --git a/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx b/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx
index 9fbe93a3bef4b398c08332fb8af6e3d3ec3d1ff8..313d76887bfd84d0a2e8e70c323a008b2946a2d0 100644
--- a/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/RevisionHistoryApp.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import { connect } from "react-redux";
 
-import RevisionHistory from "../components/revisions/RevisionHistory.jsx";
+import RevisionHistory from "../components/revisions/RevisionHistory";
 import Metrics from "metabase/entities/metrics";
 import Segments from "metabase/entities/segments";
 
diff --git a/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx b/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
index ec0c94d8d25687a04780f4f2d6382e9b604c910b..07fc554995bf362eacd91cb84c40f24c905c69a9 100644
--- a/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
@@ -4,7 +4,7 @@ import { push } from "react-router-redux";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
 
-import SegmentForm from "./SegmentForm.jsx";
+import SegmentForm from "./SegmentForm";
 
 import { updatePreviewSummary } from "../datamodel";
 import { getPreviewSummary } from "../selectors";
diff --git a/frontend/src/metabase/admin/datamodel/containers/SegmentForm.jsx b/frontend/src/metabase/admin/datamodel/containers/SegmentForm.jsx
index 8c1dfe72e42369cf17e8a279999a37a8c3f38bf1..ea6b470d1302a154290f045e71eedc0418075639 100644
--- a/frontend/src/metabase/admin/datamodel/containers/SegmentForm.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/SegmentForm.jsx
@@ -1,11 +1,11 @@
 import React, { Component } from "react";
 import { Link } from "react-router";
 
-import FormLabel from "../components/FormLabel.jsx";
-import FormInput from "../components/FormInput.jsx";
-import FormTextArea from "../components/FormTextArea.jsx";
-import FieldSet from "metabase/components/FieldSet.jsx";
-import PartialQueryBuilder from "../components/PartialQueryBuilder.jsx";
+import FormLabel from "../components/FormLabel";
+import FormInput from "../components/FormInput";
+import FormTextArea from "../components/FormTextArea";
+import FieldSet from "metabase/components/FieldSet";
+import PartialQueryBuilder from "../components/PartialQueryBuilder";
 import { t } from "ttag";
 import { formatValue } from "metabase/lib/formatting";
 
@@ -64,7 +64,7 @@ export default class SegmentForm extends Component {
       ...datasetQuery,
       query: {
         ...datasetQuery.query,
-        aggregation: ["count"],
+        aggregation: [["count"]],
       },
     });
   }
diff --git a/frontend/src/metabase/admin/datamodel/containers/TableSettingsApp.jsx b/frontend/src/metabase/admin/datamodel/containers/TableSettingsApp.jsx
index 24c6c3e6246b8a75b01c813d85f53f63157cc9d9..34a65c9243867ca525f157933b607c47cff72fee 100644
--- a/frontend/src/metabase/admin/datamodel/containers/TableSettingsApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/TableSettingsApp.jsx
@@ -4,7 +4,7 @@ import { connect } from "react-redux";
 import { t } from "ttag";
 import Breadcrumbs from "metabase/components/Breadcrumbs";
 import { BackButton } from "metabase/admin/datamodel/containers/FieldApp";
-import ActionButton from "metabase/components/ActionButton.jsx";
+import ActionButton from "metabase/components/ActionButton";
 import Section, { SectionHeader } from "../components/Section";
 
 import Databases from "metabase/entities/databases";
diff --git a/frontend/src/metabase/admin/people/components/GroupDetail.jsx b/frontend/src/metabase/admin/people/components/GroupDetail.jsx
index cb2f5d4b0b952ae83c382533b21a9c8e3941189c..033b586a7ffff8185b1b5f3a76a71412989694d3 100644
--- a/frontend/src/metabase/admin/people/components/GroupDetail.jsx
+++ b/frontend/src/metabase/admin/people/components/GroupDetail.jsx
@@ -10,22 +10,22 @@ import {
   getGroupNameLocalized,
 } from "metabase/lib/groups";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import { PermissionsApi } from "metabase/services";
 import { t } from "ttag";
-import Icon from "metabase/components/Icon.jsx";
-import Popover from "metabase/components/Popover.jsx";
-import UserAvatar from "metabase/components/UserAvatar.jsx";
-import AdminEmptyText from "metabase/components/AdminEmptyText.jsx";
-import Alert from "metabase/components/Alert.jsx";
+import Icon from "metabase/components/Icon";
+import Popover from "metabase/components/Popover";
+import UserAvatar from "metabase/components/UserAvatar";
+import AdminEmptyText from "metabase/components/AdminEmptyText";
+import Alert from "metabase/components/Alert";
 
-import AdminContentTable from "metabase/components/AdminContentTable.jsx";
-import AdminPaneLayout from "metabase/components/AdminPaneLayout.jsx";
+import AdminContentTable from "metabase/components/AdminContentTable";
+import AdminPaneLayout from "metabase/components/AdminPaneLayout";
 
-import Typeahead from "metabase/hoc/Typeahead.jsx";
+import Typeahead from "metabase/hoc/Typeahead";
 
-import AddRow from "./AddRow.jsx";
+import AddRow from "./AddRow";
 
 const GroupDescription = ({ group }) =>
   isDefaultGroup(group) ? (
@@ -71,11 +71,11 @@ const AddMemberAutocompleteSuggestion = ({
 );
 
 const COLORS = [
-  colors["brand"],
-  colors["accent1"],
-  colors["accent2"],
-  colors["accent3"],
-  colors["accent4"],
+  color("brand"),
+  color("accent1"),
+  color("accent2"),
+  color("accent3"),
+  color("accent4"),
 ];
 
 const AddMemberTypeahead = Typeahead({
diff --git a/frontend/src/metabase/admin/people/components/GroupSelect.jsx b/frontend/src/metabase/admin/people/components/GroupSelect.jsx
index 34b3eb36f2b9053ac0c4167d23ebe30736265120..5ab714823a3509c57885ac6d2eb21464caf23d1a 100644
--- a/frontend/src/metabase/admin/people/components/GroupSelect.jsx
+++ b/frontend/src/metabase/admin/people/components/GroupSelect.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import CheckBox from "metabase/components/CheckBox.jsx";
+import CheckBox from "metabase/components/CheckBox";
 
 import {
   isDefaultGroup,
diff --git a/frontend/src/metabase/admin/people/components/GroupsListing.jsx b/frontend/src/metabase/admin/people/components/GroupsListing.jsx
index 980a135120014c0684660c7e79b4f1c52d61e3c0..a94a1a2e2ea57f5be0d8104222145e87419f027c 100644
--- a/frontend/src/metabase/admin/people/components/GroupsListing.jsx
+++ b/frontend/src/metabase/admin/people/components/GroupsListing.jsx
@@ -13,18 +13,18 @@ import {
 import { KEYCODE_ENTER } from "metabase/lib/keyboard";
 
 import { t } from "ttag";
-import Icon from "metabase/components/Icon.jsx";
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
-import ModalContent from "metabase/components/ModalContent.jsx";
-import Alert from "metabase/components/Alert.jsx";
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import UserAvatar from "metabase/components/UserAvatar.jsx";
-
-import AdminContentTable from "metabase/components/AdminContentTable.jsx";
-import AdminPaneLayout from "metabase/components/AdminPaneLayout.jsx";
-
-import AddRow from "./AddRow.jsx";
+import Icon from "metabase/components/Icon";
+import InputBlurChange from "metabase/components/InputBlurChange";
+import ModalContent from "metabase/components/ModalContent";
+import Alert from "metabase/components/Alert";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import UserAvatar from "metabase/components/UserAvatar";
+
+import AdminContentTable from "metabase/components/AdminContentTable";
+import AdminPaneLayout from "metabase/components/AdminPaneLayout";
+
+import AddRow from "./AddRow";
 
 // ------------------------------------------------------------ Add Group ------------------------------------------------------------
 
diff --git a/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx b/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx
index 67cc0dbbf287371c15ebbc39b4e981c9ff42c014..537a1a229f5fd42636ef45edf0780244fdc97519 100644
--- a/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx
+++ b/frontend/src/metabase/admin/people/components/UserGroupSelect.jsx
@@ -3,13 +3,13 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
 
-import Icon from "metabase/components/Icon.jsx";
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import CheckBox from "metabase/components/CheckBox.jsx";
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
+import Icon from "metabase/components/Icon";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import CheckBox from "metabase/components/CheckBox";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
 
-import GroupSelect from "./GroupSelect.jsx";
-import GroupSummary from "./GroupSummary.jsx";
+import GroupSelect from "./GroupSelect";
+import GroupSummary from "./GroupSummary";
 
 const GroupOption = ({ name, color, selected, disabled, onChange }) => (
   <div
diff --git a/frontend/src/metabase/admin/people/containers/AdminPeopleApp.jsx b/frontend/src/metabase/admin/people/containers/AdminPeopleApp.jsx
index 463f62c83908663f94aca0bbf29c2918d31fd25b..cd3b9efbb2a3ce946d7889698a98b9eaa99ebcf7 100644
--- a/frontend/src/metabase/admin/people/containers/AdminPeopleApp.jsx
+++ b/frontend/src/metabase/admin/people/containers/AdminPeopleApp.jsx
@@ -3,12 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 
-import {
-  LeftNavPane,
-  LeftNavPaneItem,
-} from "metabase/components/LeftNavPane.jsx";
+import { LeftNavPane, LeftNavPaneItem } from "metabase/components/LeftNavPane";
 
-import AdminLayout from "metabase/components/AdminLayout.jsx";
+import AdminLayout from "metabase/components/AdminLayout";
 
 export default class AdminPeopleApp extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/admin/people/containers/GroupDetailApp.jsx b/frontend/src/metabase/admin/people/containers/GroupDetailApp.jsx
index d716d6a9f60ff9e692cdc4db146c6e445df0010b..95c244b97877aff995d47178cae750e27d84a0ae 100644
--- a/frontend/src/metabase/admin/people/containers/GroupDetailApp.jsx
+++ b/frontend/src/metabase/admin/people/containers/GroupDetailApp.jsx
@@ -6,7 +6,7 @@ import Group from "metabase/entities/groups";
 import { getUsersWithMemberships } from "../selectors";
 import { getUser } from "metabase/selectors/user";
 
-import GroupDetail from "../components/GroupDetail.jsx";
+import GroupDetail from "../components/GroupDetail";
 
 @User.loadList()
 @Group.load({ id: (state, props) => props.params.groupId })
diff --git a/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx b/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx
index 048d85880135d42ec73312f011779cf7a1089be7..925c5e0abdc402b564fb890cd7b0be13cf84c34c 100644
--- a/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx
+++ b/frontend/src/metabase/admin/people/containers/GroupsListingApp.jsx
@@ -2,7 +2,7 @@ import React from "react";
 import { connect } from "react-redux";
 
 import Group from "metabase/entities/groups";
-import GroupsListing from "../components/GroupsListing.jsx";
+import GroupsListing from "../components/GroupsListing";
 import { getGroupsWithoutMetabot } from "../selectors";
 
 @Group.loadList()
diff --git a/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx b/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
index 95d91db640e00bf306dd0d6e85fdeced5bdfb29b..a77ac3272ba7f44fd97e82380c604fce7c87cae8 100644
--- a/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
+++ b/frontend/src/metabase/admin/people/containers/PeopleListingApp.jsx
@@ -7,19 +7,19 @@ import { t } from "ttag";
 import _ from "underscore";
 import moment from "moment";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import * as Urls from "metabase/lib/urls";
 
-import AdminPaneLayout from "metabase/components/AdminPaneLayout.jsx";
+import AdminPaneLayout from "metabase/components/AdminPaneLayout";
 import EntityMenu from "metabase/components/EntityMenu";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 import Link from "metabase/components/Link";
 import Radio from "metabase/components/Radio";
-import Tooltip from "metabase/components/Tooltip.jsx";
-import UserAvatar from "metabase/components/UserAvatar.jsx";
+import Tooltip from "metabase/components/Tooltip";
+import UserAvatar from "metabase/components/UserAvatar";
 
-import UserGroupSelect from "../components/UserGroupSelect.jsx";
+import UserGroupSelect from "../components/UserGroupSelect";
 
 import { loadMemberships, createMembership, deleteMembership } from "../people";
 import {
@@ -142,9 +142,7 @@ export default class PeopleListingApp extends Component {
                     <span className="text-white inline-block">
                       <UserAvatar
                         bg={
-                          user.is_superuser
-                            ? colors["accent2"]
-                            : colors["brand"]
+                          user.is_superuser ? color("accent2") : color("brand")
                         }
                         user={user}
                       />
diff --git a/frontend/src/metabase/admin/permissions/components/PermissionsEditor.jsx b/frontend/src/metabase/admin/permissions/components/PermissionsEditor.jsx
index ef72e327408db80553b4e5c9e826a44d4b217db1..0efc85327fab3c80521b60febf357d14d3f93d32 100644
--- a/frontend/src/metabase/admin/permissions/components/PermissionsEditor.jsx
+++ b/frontend/src/metabase/admin/permissions/components/PermissionsEditor.jsx
@@ -1,12 +1,12 @@
 import React from "react";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
-import Confirm from "metabase/components/Confirm.jsx";
-import PermissionsGrid from "../components/PermissionsGrid.jsx";
-import PermissionsConfirm from "../components/PermissionsConfirm.jsx";
-import PermissionsTabs from "../components/PermissionsTabs.jsx";
-import EditBar from "metabase/components/EditBar.jsx";
-import Breadcrumbs from "metabase/components/Breadcrumbs.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import Confirm from "metabase/components/Confirm";
+import PermissionsGrid from "../components/PermissionsGrid";
+import PermissionsConfirm from "../components/PermissionsConfirm";
+import PermissionsTabs from "../components/PermissionsTabs";
+import EditBar from "metabase/components/EditBar";
+import Breadcrumbs from "metabase/components/Breadcrumbs";
 import Button from "metabase/components/Button";
 import { t } from "ttag";
 import cx from "classnames";
diff --git a/frontend/src/metabase/admin/permissions/components/PermissionsGrid.jsx b/frontend/src/metabase/admin/permissions/components/PermissionsGrid.jsx
index d7c21cba8cf22666174c6406aa38a567e528f20e..ace4ff30d9a6e356e35521643d1570a77c8e75b5 100644
--- a/frontend/src/metabase/admin/permissions/components/PermissionsGrid.jsx
+++ b/frontend/src/metabase/admin/permissions/components/PermissionsGrid.jsx
@@ -5,23 +5,23 @@ import { connect } from "react-redux";
 
 import { Link } from "react-router";
 
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import ConfirmContent from "metabase/components/ConfirmContent.jsx";
-import Modal from "metabase/components/Modal.jsx";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import Tooltip from "metabase/components/Tooltip";
+import Icon from "metabase/components/Icon";
+import ConfirmContent from "metabase/components/ConfirmContent";
+import Modal from "metabase/components/Modal";
 
-import FixedHeaderGrid from "./FixedHeaderGrid.jsx";
+import FixedHeaderGrid from "./FixedHeaderGrid";
 import { AutoSizer } from "react-virtualized";
 
 import { isAdminGroup, getGroupNameLocalized } from "metabase/lib/groups";
 import cx from "classnames";
 import _ from "underscore";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
-const LIGHT_BORDER = colors["text-light"];
-const DARK_BORDER = colors["text-medium"];
+const LIGHT_BORDER = color("text-light");
+const DARK_BORDER = color("text-medium");
 const BORDER_RADIUS = 4;
 
 const getBorderStyles = ({
@@ -48,8 +48,8 @@ const HEADER_WIDTH = 240;
 
 const DEFAULT_OPTION = {
   icon: "unknown",
-  iconColor: colors["text-medium"],
-  bgColor: colors["bg-medium"],
+  iconColor: color("text-medium"),
+  bgColor: color("bg-medium"),
 };
 
 const PermissionsHeader = ({ permissions, isFirst, isLast }) => (
@@ -274,7 +274,7 @@ class GroupPermissionCell extends Component {
                 size={28}
                 style={{
                   color: this.state.hovered
-                    ? colors["text-white"]
+                    ? color("text-white")
                     : option.iconColor,
                 }}
               />
diff --git a/frontend/src/metabase/admin/permissions/containers/CollectionPermissionsModal.jsx b/frontend/src/metabase/admin/permissions/containers/CollectionPermissionsModal.jsx
index bba51b9de7d5ffd66b902a4696af4cf9f96b93e8..a1d25ef06de31a807be98e7094b935898f47d93d 100644
--- a/frontend/src/metabase/admin/permissions/containers/CollectionPermissionsModal.jsx
+++ b/frontend/src/metabase/admin/permissions/containers/CollectionPermissionsModal.jsx
@@ -5,7 +5,7 @@ import { t } from "ttag";
 import ModalContent from "metabase/components/ModalContent";
 import Button from "metabase/components/Button";
 import Link from "metabase/components/Link";
-import PermissionsGrid from "../components/PermissionsGrid.jsx";
+import PermissionsGrid from "../components/PermissionsGrid";
 import fitViewport from "metabase/hoc/FitViewPort";
 
 import { CollectionsApi } from "metabase/services";
diff --git a/frontend/src/metabase/admin/permissions/containers/CollectionsPermissionsApp.jsx b/frontend/src/metabase/admin/permissions/containers/CollectionsPermissionsApp.jsx
index cd5c6735a8156ffc67b72260b42698f4b7a39d74..12ece333133f6494e3e569e2dee1bf0b4f86560a 100644
--- a/frontend/src/metabase/admin/permissions/containers/CollectionsPermissionsApp.jsx
+++ b/frontend/src/metabase/admin/permissions/containers/CollectionsPermissionsApp.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 import { connect } from "react-redux";
 
-import PermissionsEditor from "../components/PermissionsEditor.jsx";
-import PermissionsApp from "./PermissionsApp.jsx";
+import PermissionsEditor from "../components/PermissionsEditor";
+import PermissionsApp from "./PermissionsApp";
 import fitViewport from "metabase/hoc/FitViewPort";
 
 import { CollectionsApi } from "metabase/services";
diff --git a/frontend/src/metabase/admin/permissions/containers/DataPermissionsApp.jsx b/frontend/src/metabase/admin/permissions/containers/DataPermissionsApp.jsx
index 1ef7ec0d75b4d6ba7d0809918dc13bc20d1c07d9..e00095eb2c6c86e2e812ac9b9d242424650cc075 100644
--- a/frontend/src/metabase/admin/permissions/containers/DataPermissionsApp.jsx
+++ b/frontend/src/metabase/admin/permissions/containers/DataPermissionsApp.jsx
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
 
 import fitViewport from "metabase/hoc/FitViewPort";
 
-import PermissionsApp from "./PermissionsApp.jsx";
+import PermissionsApp from "./PermissionsApp";
 
 import { PermissionsApi } from "metabase/services";
 import { fetchRealDatabases } from "metabase/redux/metadata";
diff --git a/frontend/src/metabase/admin/permissions/containers/DatabasesPermissionsApp.jsx b/frontend/src/metabase/admin/permissions/containers/DatabasesPermissionsApp.jsx
index d3dce2903c9efc1359b8f4bb075db3b9d702a5e9..c5a1849fee103bf58c7c581e679db057393cb46d 100644
--- a/frontend/src/metabase/admin/permissions/containers/DatabasesPermissionsApp.jsx
+++ b/frontend/src/metabase/admin/permissions/containers/DatabasesPermissionsApp.jsx
@@ -1,7 +1,7 @@
 import { connect } from "react-redux";
 import { push } from "react-router-redux";
 
-import PermissionsEditor from "../components/PermissionsEditor.jsx";
+import PermissionsEditor from "../components/PermissionsEditor";
 
 import {
   getDatabasesPermissionsGrid,
diff --git a/frontend/src/metabase/admin/permissions/containers/PermissionsApp.jsx b/frontend/src/metabase/admin/permissions/containers/PermissionsApp.jsx
index c2bac3e95880ef286cecdf1315cb7b802b054dff..acbc88dceba7c037d18e7ab41a6bd0a190a44add 100644
--- a/frontend/src/metabase/admin/permissions/containers/PermissionsApp.jsx
+++ b/frontend/src/metabase/admin/permissions/containers/PermissionsApp.jsx
@@ -7,8 +7,8 @@ import { push } from "react-router-redux";
 import { initialize } from "../permissions";
 import { getIsDirty } from "../selectors";
 import { t } from "ttag";
-import ConfirmContent from "metabase/components/ConfirmContent.jsx";
-import Modal from "metabase/components/Modal.jsx";
+import ConfirmContent from "metabase/components/ConfirmContent";
+import Modal from "metabase/components/Modal";
 
 const mapStateToProps = (state, props) => ({
   isDirty: getIsDirty(state, props),
diff --git a/frontend/src/metabase/admin/permissions/containers/SchemasPermissionsApp.jsx b/frontend/src/metabase/admin/permissions/containers/SchemasPermissionsApp.jsx
index 717755aacfc3edd699158aec1da212f38c905e80..fd699545d0ebbc99ba6dbc9fa2991921562e006c 100644
--- a/frontend/src/metabase/admin/permissions/containers/SchemasPermissionsApp.jsx
+++ b/frontend/src/metabase/admin/permissions/containers/SchemasPermissionsApp.jsx
@@ -1,7 +1,7 @@
 import { connect } from "react-redux";
 import { push } from "react-router-redux";
 
-import PermissionsEditor from "../components/PermissionsEditor.jsx";
+import PermissionsEditor from "../components/PermissionsEditor";
 
 import {
   getSchemasPermissionsGrid,
diff --git a/frontend/src/metabase/admin/permissions/containers/TablesPermissionsApp.jsx b/frontend/src/metabase/admin/permissions/containers/TablesPermissionsApp.jsx
index 097f54a53c061c127a7f9c7a69a1a6e1068d6338..f415a3777712ffa623f1c024be9d6caa020abbcb 100644
--- a/frontend/src/metabase/admin/permissions/containers/TablesPermissionsApp.jsx
+++ b/frontend/src/metabase/admin/permissions/containers/TablesPermissionsApp.jsx
@@ -1,7 +1,7 @@
 import { connect } from "react-redux";
 import { push } from "react-router-redux";
 
-import PermissionsEditor from "../components/PermissionsEditor.jsx";
+import PermissionsEditor from "../components/PermissionsEditor";
 
 import {
   getTablesPermissionsGrid,
diff --git a/frontend/src/metabase/admin/permissions/routes.jsx b/frontend/src/metabase/admin/permissions/routes.jsx
index 4a2ed7055d3912cf32afc5bda5bd3f5d389a91a9..3a1c7b5155c51e2c50418b199eb2885e1e90ddaf 100644
--- a/frontend/src/metabase/admin/permissions/routes.jsx
+++ b/frontend/src/metabase/admin/permissions/routes.jsx
@@ -2,11 +2,11 @@ import React from "react";
 import { Route } from "metabase/hoc/Title";
 import { IndexRedirect, IndexRoute } from "react-router";
 import { t } from "ttag";
-import DataPermissionsApp from "./containers/DataPermissionsApp.jsx";
-import DatabasesPermissionsApp from "./containers/DatabasesPermissionsApp.jsx";
-import SchemasPermissionsApp from "./containers/SchemasPermissionsApp.jsx";
-import TablesPermissionsApp from "./containers/TablesPermissionsApp.jsx";
-import CollectionPermissions from "./containers/CollectionsPermissionsApp.jsx";
+import DataPermissionsApp from "./containers/DataPermissionsApp";
+import DatabasesPermissionsApp from "./containers/DatabasesPermissionsApp";
+import SchemasPermissionsApp from "./containers/SchemasPermissionsApp";
+import TablesPermissionsApp from "./containers/TablesPermissionsApp";
+import CollectionPermissions from "./containers/CollectionsPermissionsApp";
 
 const getRoutes = store => (
   <Route title={t`Permissions`} path="permissions">
diff --git a/frontend/src/metabase/admin/permissions/selectors.js b/frontend/src/metabase/admin/permissions/selectors.js
index 038fd89febc815d0f1c22dbf3028d436fa34d1d6..ba4d40404cfd45d3d941892102a58cd26a4d8cbc 100644
--- a/frontend/src/metabase/admin/permissions/selectors.js
+++ b/frontend/src/metabase/admin/permissions/selectors.js
@@ -7,7 +7,7 @@ import { push } from "react-router-redux";
 import TogglePropagateAction from "./containers/TogglePropagateAction";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
-import colors, { alpha } from "metabase/lib/colors";
+import { color, alpha } from "metabase/lib/colors";
 
 import { t } from "ttag";
 
@@ -234,18 +234,18 @@ const BG_ALPHA = 0.15;
 
 const OPTION_GREEN = {
   icon: "check",
-  iconColor: colors["success"],
-  bgColor: alpha(colors["success"], BG_ALPHA),
+  iconColor: color("success"),
+  bgColor: alpha(color("success"), BG_ALPHA),
 };
 const OPTION_YELLOW = {
   icon: "eye",
-  iconColor: colors["warning"],
-  bgColor: alpha(colors["warning"], BG_ALPHA),
+  iconColor: color("warning"),
+  bgColor: alpha(color("warning"), BG_ALPHA),
 };
 const OPTION_RED = {
   icon: "close",
-  iconColor: colors["error"],
-  bgColor: alpha(colors["error"], BG_ALPHA),
+  iconColor: color("error"),
+  bgColor: alpha(color("error"), BG_ALPHA),
 };
 
 const OPTION_ALL = {
diff --git a/frontend/src/metabase/admin/routes.jsx b/frontend/src/metabase/admin/routes.jsx
index 0dccf05efb7f565476ab1b5a36aa120d584a8836..fe3ed2444ed9da48653403c0ba92bc71d302f283 100644
--- a/frontend/src/metabase/admin/routes.jsx
+++ b/frontend/src/metabase/admin/routes.jsx
@@ -13,20 +13,20 @@ import EditUserModal from "metabase/admin/people/containers/EditUserModal";
 import UserActivationModal from "metabase/admin/people/containers/UserActivationModal";
 
 // Settings
-import SettingsEditorApp from "metabase/admin/settings/containers/SettingsEditorApp.jsx";
+import SettingsEditorApp from "metabase/admin/settings/containers/SettingsEditorApp";
 
 //  DB Add / list
-import DatabaseListApp from "metabase/admin/databases/containers/DatabaseListApp.jsx";
-import DatabaseEditApp from "metabase/admin/databases/containers/DatabaseEditApp.jsx";
+import DatabaseListApp from "metabase/admin/databases/containers/DatabaseListApp";
+import DatabaseEditApp from "metabase/admin/databases/containers/DatabaseEditApp";
 
 // Metadata / Data model
-import MetadataEditorApp from "metabase/admin/datamodel/containers/MetadataEditorApp.jsx";
-import MetricApp from "metabase/admin/datamodel/containers/MetricApp.jsx";
-import SegmentApp from "metabase/admin/datamodel/containers/SegmentApp.jsx";
-import RevisionHistoryApp from "metabase/admin/datamodel/containers/RevisionHistoryApp.jsx";
-import AdminPeopleApp from "metabase/admin/people/containers/AdminPeopleApp.jsx";
-import FieldApp from "metabase/admin/datamodel/containers/FieldApp.jsx";
-import TableSettingsApp from "metabase/admin/datamodel/containers/TableSettingsApp.jsx";
+import MetadataEditorApp from "metabase/admin/datamodel/containers/MetadataEditorApp";
+import MetricApp from "metabase/admin/datamodel/containers/MetricApp";
+import SegmentApp from "metabase/admin/datamodel/containers/SegmentApp";
+import RevisionHistoryApp from "metabase/admin/datamodel/containers/RevisionHistoryApp";
+import AdminPeopleApp from "metabase/admin/people/containers/AdminPeopleApp";
+import FieldApp from "metabase/admin/datamodel/containers/FieldApp";
+import TableSettingsApp from "metabase/admin/datamodel/containers/TableSettingsApp";
 
 import TroubleshootingApp from "metabase/admin/tasks/containers/TroubleshootingApp";
 import TasksApp from "metabase/admin/tasks/containers/TasksApp";
@@ -36,11 +36,11 @@ import JobTriggersModal from "metabase/admin/tasks/containers/JobTriggersModal";
 import Logs from "metabase/admin/tasks/containers/Logs";
 
 // People
-import PeopleListingApp from "metabase/admin/people/containers/PeopleListingApp.jsx";
-import GroupsListingApp from "metabase/admin/people/containers/GroupsListingApp.jsx";
-import GroupDetailApp from "metabase/admin/people/containers/GroupDetailApp.jsx";
+import PeopleListingApp from "metabase/admin/people/containers/PeopleListingApp";
+import GroupsListingApp from "metabase/admin/people/containers/GroupsListingApp";
+import GroupDetailApp from "metabase/admin/people/containers/GroupDetailApp";
 
-import getAdminPermissionsRoutes from "metabase/admin/permissions/routes.jsx";
+import getAdminPermissionsRoutes from "metabase/admin/permissions/routes";
 
 const getRoutes = (store, IsAdmin) => (
   <Route
diff --git a/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx b/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx
index f3c1502dc57d6973b943dff6546cdae0b7ac1263..e946b00ce4367be8fd2ffd9be86f9b6d56dfc243 100644
--- a/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx
+++ b/frontend/src/metabase/admin/settings/components/SettingsSetting.jsx
@@ -2,14 +2,14 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { assocIn } from "icepick";
 
-import SettingHeader from "./SettingHeader.jsx";
+import SettingHeader from "./SettingHeader";
 import { t } from "ttag";
-import SettingInput from "./widgets/SettingInput.jsx";
-import SettingNumber from "./widgets/SettingNumber.jsx";
-import SettingPassword from "./widgets/SettingPassword.jsx";
-import SettingRadio from "./widgets/SettingRadio.jsx";
-import SettingToggle from "./widgets/SettingToggle.jsx";
-import SettingSelect from "./widgets/SettingSelect.jsx";
+import SettingInput from "./widgets/SettingInput";
+import SettingNumber from "./widgets/SettingNumber";
+import SettingPassword from "./widgets/SettingPassword";
+import SettingRadio from "./widgets/SettingRadio";
+import SettingToggle from "./widgets/SettingToggle";
+import SettingSelect from "./widgets/SettingSelect";
 
 const SETTING_WIDGET_MAP = {
   string: SettingInput,
diff --git a/frontend/src/metabase/admin/settings/components/SettingsSetupList.jsx b/frontend/src/metabase/admin/settings/components/SettingsSetupList.jsx
index 62c62e7b6d8e0f0ae8312772d2676cbdbff92a65..27221bf3438d7d75d6ff7bd79453e498fd1fdfd1 100644
--- a/frontend/src/metabase/admin/settings/components/SettingsSetupList.jsx
+++ b/frontend/src/metabase/admin/settings/components/SettingsSetupList.jsx
@@ -1,10 +1,10 @@
 import React, { Component } from "react";
 import { Link } from "react-router";
-import Icon from "metabase/components/Icon.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import Icon from "metabase/components/Icon";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import { SetupApi } from "metabase/services";
 import { t } from "ttag";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const TaskList = ({ tasks }) => (
   <ol>
@@ -41,14 +41,14 @@ const CompletionBadge = ({ completed }) => (
     style={{
       borderWidth: 1,
       borderStyle: "solid",
-      borderColor: completed ? colors["success"] : colors["text-light"],
-      backgroundColor: completed ? colors["success"] : colors["text-white"],
+      borderColor: completed ? color("success") : color("text-light"),
+      backgroundColor: completed ? color("success") : color("text-white"),
       width: 32,
       height: 32,
       borderRadius: 99,
     }}
   >
-    {completed && <Icon name="check" color={colors["text-white"]} />}
+    {completed && <Icon name="check" color={color("text-white")} />}
   </div>
 );
 
diff --git a/frontend/src/metabase/admin/settings/components/SettingsSingleSignOnForm.jsx b/frontend/src/metabase/admin/settings/components/SettingsSingleSignOnForm.jsx
index 07351faa5b5de4bd059752d8fb5fd2a12dc56a62..e55c289286981e2a393a677ec67d482bacdfa101 100644
--- a/frontend/src/metabase/admin/settings/components/SettingsSingleSignOnForm.jsx
+++ b/frontend/src/metabase/admin/settings/components/SettingsSingleSignOnForm.jsx
@@ -4,8 +4,8 @@ import cx from "classnames";
 import _ from "underscore";
 import { t, jt } from "ttag";
 
-import Breadcrumbs from "metabase/components/Breadcrumbs.jsx";
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
+import Breadcrumbs from "metabase/components/Breadcrumbs";
+import InputBlurChange from "metabase/components/InputBlurChange";
 
 export default class SettingsSingleSignOnForm extends Component {
   constructor(props, context) {
diff --git a/frontend/src/metabase/admin/settings/components/SettingsSlackForm.jsx b/frontend/src/metabase/admin/settings/components/SettingsSlackForm.jsx
index c2400c1e5b47d21ea1b6b65f53924837832bfe99..a882df7a6b677c38f64012feafcf5e79c97069e6 100644
--- a/frontend/src/metabase/admin/settings/components/SettingsSlackForm.jsx
+++ b/frontend/src/metabase/admin/settings/components/SettingsSlackForm.jsx
@@ -2,10 +2,10 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import MetabaseUtils from "metabase/lib/utils";
-import SettingsSetting from "./SettingsSetting.jsx";
+import SettingsSetting from "./SettingsSetting";
 
 import Button from "metabase/components/Button";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 import RetinaImage from "react-retina-image";
 
diff --git a/frontend/src/metabase/admin/settings/components/SettingsUpdatesForm.jsx b/frontend/src/metabase/admin/settings/components/SettingsUpdatesForm.jsx
index fd83d9216377d09d6dbf6662737df2589c324408..643bfd42b30f2f264eb2372f520fc7df38129652 100644
--- a/frontend/src/metabase/admin/settings/components/SettingsUpdatesForm.jsx
+++ b/frontend/src/metabase/admin/settings/components/SettingsUpdatesForm.jsx
@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
 import { t, jt } from "ttag";
 import MetabaseSettings from "metabase/lib/settings";
 import MetabaseUtils from "metabase/lib/utils";
-import SettingsSetting from "./SettingsSetting.jsx";
+import SettingsSetting from "./SettingsSetting";
 
 import _ from "underscore";
 
diff --git a/frontend/src/metabase/admin/settings/components/widgets/CustomGeoJSONWidget.jsx b/frontend/src/metabase/admin/settings/components/widgets/CustomGeoJSONWidget.jsx
index 0403621cd415be0defa101ad39506dff2bd222f4..e52cc4b8adb614185b61822cfe75101f3f4fbca9 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/CustomGeoJSONWidget.jsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/CustomGeoJSONWidget.jsx
@@ -3,19 +3,19 @@ import PropTypes from "prop-types";
 import { t } from "ttag";
 
 import Utils from "metabase/lib/utils";
-import Select, { Option } from "metabase/components/Select.jsx";
-import Confirm from "metabase/components/Confirm.jsx";
-import Ellipsified from "metabase/components/Ellipsified.jsx";
-import Modal from "metabase/components/Modal.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import Select, { Option } from "metabase/components/Select";
+import Confirm from "metabase/components/Confirm";
+import Ellipsified from "metabase/components/Ellipsified";
+import Modal from "metabase/components/Modal";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import SettingHeader from "../SettingHeader.jsx";
+import SettingHeader from "../SettingHeader";
 
 import { SettingsApi, GeoJSONApi } from "metabase/services";
 
 import cx from "classnames";
 
-import LeafletChoropleth from "metabase/visualizations/components/LeafletChoropleth.jsx";
+import LeafletChoropleth from "metabase/visualizations/components/LeafletChoropleth";
 
 import pure from "recompose/pure";
 
diff --git a/frontend/src/metabase/admin/settings/components/widgets/SettingInput.jsx b/frontend/src/metabase/admin/settings/components/widgets/SettingInput.jsx
index bde7ab9dcf2261e9ca8ccdc73c3c92e159067e3a..4febc8303b97aa0d085812f6779c1c56ea390674 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/SettingInput.jsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/SettingInput.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
+import InputBlurChange from "metabase/components/InputBlurChange";
 import cx from "classnames";
 
 const SettingInput = ({
diff --git a/frontend/src/metabase/admin/settings/components/widgets/SettingPassword.jsx b/frontend/src/metabase/admin/settings/components/widgets/SettingPassword.jsx
index 3ab5ac103a0a5255eab241d1fe3a67fb84264bd3..0277751ac06fe261107c4c2e8f6d86033682f2ed 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/SettingPassword.jsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/SettingPassword.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import SettingInput from "./SettingInput.jsx";
+import SettingInput from "./SettingInput";
 
 const SettingPassword = props => <SettingInput {...props} type="password" />;
 
diff --git a/frontend/src/metabase/admin/settings/components/widgets/SettingSelect.jsx b/frontend/src/metabase/admin/settings/components/widgets/SettingSelect.jsx
index 72c493af863080ca5de43efafc47b991de7cf640..f21abaa2a1409bdec4ffdcaed770b34fddc7480d 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/SettingSelect.jsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/SettingSelect.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Select, { Option } from "metabase/components/Select.jsx";
+import Select, { Option } from "metabase/components/Select";
 
 const SettingSelect = ({
   setting: { placeholder, value, options, defaultValue },
diff --git a/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx b/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx
index 63aa0146c1d7d2d8c2749e08891f64428b832c80..5477d9481ec5f8e15fefbebfbe2191759a0f6b01 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/SettingToggle.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 import { t } from "ttag";
-import Toggle from "metabase/components/Toggle.jsx";
+import Toggle from "metabase/components/Toggle";
 
 const SettingToggle = ({ setting, onChange, disabled }) => {
   const value = setting.value == null ? setting.default : setting.value;
diff --git a/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx b/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx
index ffb5f70bd052cfd18e7632ba665eb2a162f9e28a..5c8773d30ac76be4c3fd90a09c2696d03cd30200 100644
--- a/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx
+++ b/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx
@@ -6,17 +6,17 @@ import title from "metabase/hoc/Title";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import { slugify } from "metabase/lib/formatting";
 import { t } from "ttag";
-import AdminLayout from "metabase/components/AdminLayout.jsx";
+import AdminLayout from "metabase/components/AdminLayout";
 import { NotFound } from "metabase/containers/ErrorPages";
 
-import SettingsSetting from "../components/SettingsSetting.jsx";
-import SettingsEmailForm from "../components/SettingsEmailForm.jsx";
-import SettingsSlackForm from "../components/SettingsSlackForm.jsx";
-import SettingsLdapForm from "../components/SettingsLdapForm.jsx";
-import SettingsSetupList from "../components/SettingsSetupList.jsx";
-import SettingsUpdatesForm from "../components/SettingsUpdatesForm.jsx";
-import SettingsSingleSignOnForm from "../components/SettingsSingleSignOnForm.jsx";
-import SettingsAuthenticationOptions from "../components/SettingsAuthenticationOptions.jsx";
+import SettingsSetting from "../components/SettingsSetting";
+import SettingsEmailForm from "../components/SettingsEmailForm";
+import SettingsSlackForm from "../components/SettingsSlackForm";
+import SettingsLdapForm from "../components/SettingsLdapForm";
+import SettingsSetupList from "../components/SettingsSetupList";
+import SettingsUpdatesForm from "../components/SettingsUpdatesForm";
+import SettingsSingleSignOnForm from "../components/SettingsSingleSignOnForm";
+import SettingsAuthenticationOptions from "../components/SettingsAuthenticationOptions";
 
 import { prepareAnalyticsValue } from "metabase/admin/settings/utils";
 
diff --git a/frontend/src/metabase/admin/settings/selectors.js b/frontend/src/metabase/admin/settings/selectors.js
index 18f5be6d471a94031cd8a0af944d4fd003e3b803..212665231efcabdda1430bec361ba29a05f09294 100644
--- a/frontend/src/metabase/admin/settings/selectors.js
+++ b/frontend/src/metabase/admin/settings/selectors.js
@@ -2,14 +2,14 @@ import _ from "underscore";
 import { createSelector } from "reselect";
 import MetabaseSettings from "metabase/lib/settings";
 import { t } from "ttag";
-import CustomGeoJSONWidget from "./components/widgets/CustomGeoJSONWidget.jsx";
+import CustomGeoJSONWidget from "./components/widgets/CustomGeoJSONWidget";
 import {
   PublicLinksDashboardListing,
   PublicLinksQuestionListing,
   EmbeddedQuestionListing,
   EmbeddedDashboardListing,
-} from "./components/widgets/PublicLinksListing.jsx";
-import SecretKeyWidget from "./components/widgets/SecretKeyWidget.jsx";
+} from "./components/widgets/PublicLinksListing";
+import SecretKeyWidget from "./components/widgets/SecretKeyWidget";
 import EmbeddingLegalese from "./components/widgets/EmbeddingLegalese";
 import EmbeddingLevel from "./components/widgets/EmbeddingLevel";
 import LdapGroupMappingsWidget from "./components/widgets/LdapGroupMappingsWidget";
diff --git a/frontend/src/metabase/admin/tasks/containers/JobInfoApp.jsx b/frontend/src/metabase/admin/tasks/containers/JobInfoApp.jsx
index 98008f694b54ecdc18275e362476c735b3dfc823..5de7de8ade96feaa452ba909287f02dec74131e4 100644
--- a/frontend/src/metabase/admin/tasks/containers/JobInfoApp.jsx
+++ b/frontend/src/metabase/admin/tasks/containers/JobInfoApp.jsx
@@ -4,7 +4,7 @@ import { connect } from "react-redux";
 
 import { Box, Flex } from "grid-styled";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import AdminHeader from "metabase/components/AdminHeader";
 import Link from "metabase/components/Link";
 
diff --git a/frontend/src/metabase/admin/tasks/containers/JobTriggersModal.jsx b/frontend/src/metabase/admin/tasks/containers/JobTriggersModal.jsx
index a4ce50da6115e1a7feba2bcd6508745dc364ed34..0f4b39e62cdfbbe60b78b84f0c5a9b65618dbe6d 100644
--- a/frontend/src/metabase/admin/tasks/containers/JobTriggersModal.jsx
+++ b/frontend/src/metabase/admin/tasks/containers/JobTriggersModal.jsx
@@ -4,7 +4,7 @@ import { connect } from "react-redux";
 import { goBack } from "react-router-redux";
 import _ from "underscore";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import ModalContent from "metabase/components/ModalContent";
 
 import { fetchJobInfo } from "../jobInfo";
diff --git a/frontend/src/metabase/admin/tasks/containers/Logs.jsx b/frontend/src/metabase/admin/tasks/containers/Logs.jsx
index 247779c9ad320b56272c52825dd0e55417c3b006..8552015cd42cdb173ad7b10e2301f530d58c411a 100644
--- a/frontend/src/metabase/admin/tasks/containers/Logs.jsx
+++ b/frontend/src/metabase/admin/tasks/containers/Logs.jsx
@@ -14,17 +14,17 @@ import { t } from "ttag";
 
 import Select, { Option } from "metabase/components/Select";
 import { addCSSRule } from "metabase/lib/dom";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const ANSI_COLORS = {
-  black: colors["text-black"],
-  white: colors["text-white"],
-  gray: colors["text-medium"],
-  red: colors["saturated-red"],
-  green: colors["saturated-green"],
-  yellow: colors["saturated-yellow"],
-  blue: colors["saturated-blue"],
-  magenta: colors["saturated-purple"],
+  black: color("text-dark"),
+  white: color("text-white"),
+  gray: color("text-medium"),
+  red: color("saturated-red"),
+  green: color("saturated-green"),
+  yellow: color("saturated-yellow"),
+  blue: color("saturated-blue"),
+  magenta: color("saturated-purple"),
   cyan: "cyan",
 };
 for (const [name, color] of Object.entries(ANSI_COLORS)) {
diff --git a/frontend/src/metabase/admin/tasks/containers/TroubleshootingApp.jsx b/frontend/src/metabase/admin/tasks/containers/TroubleshootingApp.jsx
index 7f24a6cc286d295cab8d59831656492c2741711c..67a16d84e4f3615b757844991085ec43427f4b3d 100644
--- a/frontend/src/metabase/admin/tasks/containers/TroubleshootingApp.jsx
+++ b/frontend/src/metabase/admin/tasks/containers/TroubleshootingApp.jsx
@@ -3,12 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 
-import {
-  LeftNavPane,
-  LeftNavPaneItem,
-} from "metabase/components/LeftNavPane.jsx";
+import { LeftNavPane, LeftNavPaneItem } from "metabase/components/LeftNavPane";
 
-import AdminLayout from "metabase/components/AdminLayout.jsx";
+import AdminLayout from "metabase/components/AdminLayout";
 
 export default class TroubleshootingApp extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/alert/alert.js b/frontend/src/metabase/alert/alert.js
index 6682808f6a2d4bcae4d2318138bcd5b44b76587f..2fc3b7f2ca22f5da3d5a92019b3447afe7238b3f 100644
--- a/frontend/src/metabase/alert/alert.js
+++ b/frontend/src/metabase/alert/alert.js
@@ -6,7 +6,7 @@ import { addUndo } from "metabase/redux/undo";
 import { t } from "ttag";
 import { AlertApi } from "metabase/services";
 import { RestfulRequest } from "metabase/lib/request";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 export const FETCH_ALL_ALERTS = "metabase/alerts/FETCH_ALL_ALERTS";
 const fetchAllAlertsRequest = new RestfulRequest({
diff --git a/frontend/src/metabase/app-embed.js b/frontend/src/metabase/app-embed.js
index c73ea000448125c1e59c99db4979224b46b34ee7..b686ad0516e38ba1e2d7ed6ab5ed8a4b35df521d 100644
--- a/frontend/src/metabase/app-embed.js
+++ b/frontend/src/metabase/app-embed.js
@@ -5,7 +5,7 @@
 
 import { init } from "./app";
 
-import { getRoutes } from "./routes-embed.jsx";
+import { getRoutes } from "./routes-embed";
 import reducers from "./reducers-public";
 
 import { IFRAMED } from "metabase/lib/dom";
diff --git a/frontend/src/metabase/app-main.js b/frontend/src/metabase/app-main.js
index 162592ede4f19767e9e6afb218f38175571ff752..6abd3114898151eb995b11b0eda4e0d5f82d8eee 100644
--- a/frontend/src/metabase/app-main.js
+++ b/frontend/src/metabase/app-main.js
@@ -1,7 +1,7 @@
 import { push } from "react-router-redux";
 
 import { init } from "metabase/app";
-import { getRoutes } from "metabase/routes.jsx";
+import { getRoutes } from "metabase/routes";
 import reducers from "metabase/reducers-main";
 
 import api from "metabase/lib/api";
diff --git a/frontend/src/metabase/app-public.js b/frontend/src/metabase/app-public.js
index 3c2e6afa78fb1804bd0d8e493c2ba06aa0816e9c..15fa8f22d76661fd532e9ee665716d412227f8f3 100644
--- a/frontend/src/metabase/app-public.js
+++ b/frontend/src/metabase/app-public.js
@@ -1,6 +1,6 @@
 import { init } from "./app";
 
-import { getRoutes } from "./routes-public.jsx";
+import { getRoutes } from "./routes-public";
 import reducers from "./reducers-public";
 
 init(reducers, getRoutes, () => {});
diff --git a/frontend/src/metabase/auth/components/GoogleNoAccount.jsx b/frontend/src/metabase/auth/components/GoogleNoAccount.jsx
index 60dafba4bc59b7e00dbbfe6e1b1303bd093cfad5..1e67b780a4a17b18a4d1a9a2b9e5c5189ec029d7 100644
--- a/frontend/src/metabase/auth/components/GoogleNoAccount.jsx
+++ b/frontend/src/metabase/auth/components/GoogleNoAccount.jsx
@@ -1,8 +1,8 @@
 import React from "react";
 import { t } from "ttag";
-import AuthScene from "./AuthScene.jsx";
-import LogoIcon from "metabase/components/LogoIcon.jsx";
-import BackToLogin from "./BackToLogin.jsx";
+import AuthScene from "./AuthScene";
+import LogoIcon from "metabase/components/LogoIcon";
+import BackToLogin from "./BackToLogin";
 
 const GoogleNoAccount = () => (
   <div className="full-height bg-white flex flex-column flex-full md-layout-centered">
diff --git a/frontend/src/metabase/auth/components/SSOLoginButton.jsx b/frontend/src/metabase/auth/components/SSOLoginButton.jsx
index aa30f1785b4df47887fdb932331f6fab4dd27bcd..70dd6df267331a07dfb18cce8690ccdcae4031be 100644
--- a/frontend/src/metabase/auth/components/SSOLoginButton.jsx
+++ b/frontend/src/metabase/auth/components/SSOLoginButton.jsx
@@ -12,8 +12,8 @@ class SSOLoginButton extends Component {
   render() {
     const { provider } = this.props;
     return (
-      <div className="relative z2 bg-white p2 cursor-pointer shadow-hover text-centered sm-text-left rounded block sm-inline-block bordered shadowed">
-        <div className="flex align-center">
+      <div className="relative z2 bg-white p2 cursor-pointer shadow-hover text-centered sm-text-left rounded bordered shadowed flex">
+        <div className="flex align-center ml-auto mr-auto">
           <Icon className="mr1" name={provider} />
           <h4>{t`Sign in with ${capitalize(provider)}`}</h4>
         </div>
diff --git a/frontend/src/metabase/auth/containers/ForgotPasswordApp.jsx b/frontend/src/metabase/auth/containers/ForgotPasswordApp.jsx
index eaa5a42137f5c0c067a28373b8aea055aa29bd81..8c50f9f1d0510864b1fd8e1f325cad6774729c07 100644
--- a/frontend/src/metabase/auth/containers/ForgotPasswordApp.jsx
+++ b/frontend/src/metabase/auth/containers/ForgotPasswordApp.jsx
@@ -3,13 +3,13 @@ import React, { Component } from "react";
 import _ from "underscore";
 import cx from "classnames";
 import { t } from "ttag";
-import AuthScene from "../components/AuthScene.jsx";
-import BackToLogin from "../components/BackToLogin.jsx";
-import FormField from "metabase/components/form/FormField.jsx";
-import FormLabel from "metabase/components/form/FormLabel.jsx";
-import FormMessage from "metabase/components/form/FormMessage.jsx";
-import LogoIcon from "metabase/components/LogoIcon.jsx";
-import Icon from "metabase/components/Icon.jsx";
+import AuthScene from "../components/AuthScene";
+import BackToLogin from "../components/BackToLogin";
+import FormField from "metabase/components/form/FormField";
+import FormLabel from "metabase/components/form/FormLabel";
+import FormMessage from "metabase/components/form/FormMessage";
+import LogoIcon from "metabase/components/LogoIcon";
+import Icon from "metabase/components/Icon";
 
 import MetabaseSettings from "metabase/lib/settings";
 
diff --git a/frontend/src/metabase/auth/containers/LoginApp.jsx b/frontend/src/metabase/auth/containers/LoginApp.jsx
index 40679bf4a796eb1ca906c242c303da20ac715968..4de4677a4c7a83eea3ecfd766fd862c174f9b85b 100644
--- a/frontend/src/metabase/auth/containers/LoginApp.jsx
+++ b/frontend/src/metabase/auth/containers/LoginApp.jsx
@@ -4,14 +4,14 @@ import { Link } from "react-router";
 import { connect } from "react-redux";
 
 import { t } from "ttag";
-import AuthScene from "../components/AuthScene.jsx";
-import SSOLoginButton from "../components/SSOLoginButton.jsx";
+import AuthScene from "../components/AuthScene";
+import SSOLoginButton from "../components/SSOLoginButton";
 import Button from "metabase/components/Button";
 import CheckBox from "metabase/components/CheckBox";
-import FormField from "metabase/components/form/FormField.jsx";
-import FormLabel from "metabase/components/form/FormLabel.jsx";
-import FormMessage from "metabase/components/form/FormMessage.jsx";
-import LogoIcon from "metabase/components/LogoIcon.jsx";
+import FormField from "metabase/components/form/FormField";
+import FormLabel from "metabase/components/form/FormLabel";
+import FormMessage from "metabase/components/form/FormMessage";
+import LogoIcon from "metabase/components/LogoIcon";
 import Settings from "metabase/lib/settings";
 import Utils from "metabase/lib/utils";
 
@@ -113,11 +113,13 @@ export default class LoginApp extends Component {
   }
 
   render() {
-    const { loginError } = this.props;
+    const { loginError, location } = this.props;
     const ldapEnabled = Settings.ldapEnabled();
 
+    const preferUsernameAndPassword = location.query.useMBLogin;
+
     return (
-      <div className="full bg-white flex flex-column flex-full md-layout-centered">
+      <div className="bg-white flex flex-column flex-full md-layout-centered">
         <div className="Login-wrapper wrapper Grid Grid--full md-Grid--1of2 relative z2">
           <div className="Grid-cell flex layout-centered text-brand">
             <LogoIcon className="Logo my4 sm-my0" width={66} height={85} />
@@ -130,108 +132,126 @@ export default class LoginApp extends Component {
             >
               <h3 className="Login-header Form-offset">{t`Sign in to Metabase`}</h3>
 
-              {Settings.ssoEnabled() && (
-                <div className="mx4 mb4 py3 border-bottom relative">
-                  <SSOLoginButton provider="google" ref="ssoLoginButton" />
-                  {/*<div className="g-signin2 ml1 relative z2" id="g-signin2"></div>*/}
-                  <div
-                    className="mx1 absolute text-centered left right"
-                    style={{ bottom: -8 }}
-                  >
-                    <span className="text-bold px3 py2 text-medium bg-white">{t`OR`}</span>
+              {Settings.ssoEnabled() && !preferUsernameAndPassword && (
+                <div className="mx4 py3 relative my4">
+                  <div className="relative border-bottom pb4">
+                    <SSOLoginButton provider="google" ref="ssoLoginButton" />
+                    {/*<div className="g-signin2 ml1 relative z2" id="g-signin2"></div>*/}
+                    <div
+                      className="mx1 absolute text-centered left right"
+                      style={{ bottom: -8 }}
+                    >
+                      <span className="text-bold px3 py2 text-medium bg-white">{t`OR`}</span>
+                    </div>
+                  </div>
+                  <div className="py3">
+                    <Link to="/auth/login?useMBLogin=true">
+                      <Button className="EmailSignIn full">
+                        {t`Sign in with email`}
+                      </Button>
+                    </Link>
                   </div>
                 </div>
               )}
 
-              <FormMessage
-                formError={
-                  loginError && loginError.data.message ? loginError : null
-                }
-              />
-
-              <FormField
-                key="username"
-                fieldName="username"
-                formError={loginError}
-              >
-                <FormLabel
-                  title={
-                    Settings.ldapEnabled()
-                      ? t`Username or email address`
-                      : t`Email address`
-                  }
-                  fieldName={"username"}
-                  formError={loginError}
-                />
-                <input
-                  className="Form-input Form-offset full py1"
-                  name="username"
-                  placeholder="youlooknicetoday@email.com"
-                  type={
-                    /*
-                     * if a user has ldap enabled, use a text input to allow for
-                     * ldap username && schemes. if not and they're using built
-                     * in auth, set the input type to email so we get built in
-                     * validation in modern browsers
-                     * */
-                    ldapEnabled ? "text" : "email"
-                  }
-                  onChange={e => this.onChange("username", e.target.value)}
-                  autoFocus
-                />
-                <span className="Form-charm" />
-              </FormField>
-
-              <FormField
-                key="password"
-                fieldName="password"
-                formError={loginError}
-              >
-                <FormLabel
-                  title={t`Password`}
-                  fieldName={"password"}
-                  formError={loginError}
-                />
-                <input
-                  className="Form-input Form-offset full py1"
-                  name="password"
-                  placeholder="Shh..."
-                  type="password"
-                  onChange={e => this.onChange("password", e.target.value)}
-                />
-                <span className="Form-charm" />
-              </FormField>
-
-              <div className="Form-field">
-                <div className="Form-offset flex align-center">
-                  <CheckBox
-                    name="remember"
-                    checked={this.state.rememberMe}
-                    onChange={() =>
-                      this.setState({ rememberMe: !this.state.rememberMe })
+              {(!Settings.ssoEnabled() || preferUsernameAndPassword) && (
+                <div>
+                  <FormMessage
+                    formError={
+                      loginError && loginError.data.message ? loginError : null
                     }
                   />
-                  <span className="ml1">{t`Remember Me`}</span>
+
+                  <FormField
+                    key="username"
+                    fieldName="username"
+                    formError={loginError}
+                  >
+                    <FormLabel
+                      title={
+                        Settings.ldapEnabled()
+                          ? t`Username or email address`
+                          : t`Email address`
+                      }
+                      fieldName={"username"}
+                      formError={loginError}
+                    />
+                    <input
+                      className="Form-input Form-offset full py1"
+                      name="username"
+                      placeholder="youlooknicetoday@email.com"
+                      type={
+                        /*
+                         * if a user has ldap enabled, use a text input to allow for
+                         * ldap username && schemes. if not and they're using built
+                         * in auth, set the input type to email so we get built in
+                         * validation in modern browsers
+                         * */
+                        ldapEnabled ? "text" : "email"
+                      }
+                      onChange={e => this.onChange("username", e.target.value)}
+                      autoFocus
+                    />
+                    <span className="Form-charm" />
+                  </FormField>
+
+                  <FormField
+                    key="password"
+                    fieldName="password"
+                    formError={loginError}
+                  >
+                    <FormLabel
+                      title={t`Password`}
+                      fieldName={"password"}
+                      formError={loginError}
+                    />
+                    <input
+                      className="Form-input Form-offset full py1"
+                      name="password"
+                      placeholder="Shh..."
+                      type="password"
+                      onChange={e => this.onChange("password", e.target.value)}
+                    />
+                    <span className="Form-charm" />
+                  </FormField>
+
+                  <div className="Form-field">
+                    <div className="Form-offset flex align-center">
+                      <CheckBox
+                        name="remember"
+                        checked={this.state.rememberMe}
+                        onChange={() =>
+                          this.setState({
+                            rememberMe: !this.state.rememberMe,
+                          })
+                        }
+                      />
+                      <span className="ml1">{t`Remember Me`}</span>
+                    </div>
+                  </div>
+
+                  <div className="Form-actions p4">
+                    <Button
+                      primary={this.state.valid}
+                      disabled={!this.state.valid}
+                    >
+                      {t`Sign in`}
+                    </Button>
+                    <Link
+                      to={
+                        "/auth/forgot_password" +
+                        (Utils.validEmail(this.state.credentials.username)
+                          ? "?email=" + this.state.credentials.username
+                          : "")
+                      }
+                      className="Grid-cell py2 sm-py0 md-text-right text-centered flex-full link"
+                      onClick={e => {
+                        window.OSX ? window.OSX.resetPassword() : null;
+                      }}
+                    >{t`I seem to have forgotten my password`}</Link>
+                  </div>
                 </div>
-              </div>
-
-              <div className="Form-actions p4">
-                <Button primary={this.state.valid} disabled={!this.state.valid}>
-                  {t`Sign in`}
-                </Button>
-                <Link
-                  to={
-                    "/auth/forgot_password" +
-                    (Utils.validEmail(this.state.credentials.username)
-                      ? "?email=" + this.state.credentials.username
-                      : "")
-                  }
-                  className="Grid-cell py2 sm-py0 md-text-right text-centered flex-full link"
-                  onClick={e => {
-                    window.OSX ? window.OSX.resetPassword() : null;
-                  }}
-                >{t`I seem to have forgotten my password`}</Link>
-              </div>
+              )}
             </form>
           </div>
         </div>
diff --git a/frontend/src/metabase/auth/containers/PasswordResetApp.jsx b/frontend/src/metabase/auth/containers/PasswordResetApp.jsx
index fafebfc66ce8db558bce8c6c42cf216e49e4c8b6..ef0d0a080df2254e8a410e103fc0d5aaa674d18b 100644
--- a/frontend/src/metabase/auth/containers/PasswordResetApp.jsx
+++ b/frontend/src/metabase/auth/containers/PasswordResetApp.jsx
@@ -4,12 +4,12 @@ import { Link } from "react-router";
 
 import cx from "classnames";
 import { t, jt } from "ttag";
-import AuthScene from "../components/AuthScene.jsx";
-import FormField from "metabase/components/form/FormField.jsx";
-import FormLabel from "metabase/components/form/FormLabel.jsx";
-import FormMessage from "metabase/components/form/FormMessage.jsx";
-import LogoIcon from "metabase/components/LogoIcon.jsx";
-import Icon from "metabase/components/Icon.jsx";
+import AuthScene from "../components/AuthScene";
+import FormField from "metabase/components/form/FormField";
+import FormLabel from "metabase/components/form/FormLabel";
+import FormMessage from "metabase/components/form/FormMessage";
+import LogoIcon from "metabase/components/LogoIcon";
+import Icon from "metabase/components/Icon";
 
 import MetabaseSettings from "metabase/lib/settings";
 
diff --git a/frontend/src/metabase/components/AccordionList.jsx b/frontend/src/metabase/components/AccordionList.jsx
index 0c2c32e270f791e44cf4a582d42dc0cc0ca7f262..8ae5d80aae9bc066c3315daf8370e27d458604ca 100644
--- a/frontend/src/metabase/components/AccordionList.jsx
+++ b/frontend/src/metabase/components/AccordionList.jsx
@@ -5,8 +5,8 @@ import cx from "classnames";
 import _ from "underscore";
 import { color } from "metabase/lib/colors";
 
-import Icon from "metabase/components/Icon.jsx";
-import ListSearchField from "metabase/components/ListSearchField.jsx";
+import Icon from "metabase/components/Icon";
+import ListSearchField from "metabase/components/ListSearchField";
 import { List, CellMeasurer, CellMeasurerCache } from "react-virtualized";
 
 export type RenderItemWrapper = (
diff --git a/frontend/src/metabase/components/AdminAwareEmptyState.jsx b/frontend/src/metabase/components/AdminAwareEmptyState.jsx
index fdb3410b5f098bbf2ba82231ba32b8a5a6a5439c..5ec81f64b74fd1b770ba9ca159abe369b24174f0 100644
--- a/frontend/src/metabase/components/AdminAwareEmptyState.jsx
+++ b/frontend/src/metabase/components/AdminAwareEmptyState.jsx
@@ -1,5 +1,5 @@
 import React, { Component } from "react";
-import EmptyState from "metabase/components/EmptyState.jsx";
+import EmptyState from "metabase/components/EmptyState";
 import { getUser } from "metabase/selectors/user";
 import { connect } from "react-redux";
 
diff --git a/frontend/src/metabase/components/AdminHeader.jsx b/frontend/src/metabase/components/AdminHeader.jsx
index 8b21a6a6a4e85ffa72ee3354ab8434678b3792e4..992ee651f23f923c8bc37abd300bb9582f981d8e 100644
--- a/frontend/src/metabase/components/AdminHeader.jsx
+++ b/frontend/src/metabase/components/AdminHeader.jsx
@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 
-import SaveStatus from "metabase/components/SaveStatus.jsx";
+import SaveStatus from "metabase/components/SaveStatus";
 
 export default class AdminHeader extends Component {
   render() {
diff --git a/frontend/src/metabase/components/AdminLayout.jsx b/frontend/src/metabase/components/AdminLayout.jsx
index d0e7079aa7171b63bdb6c93550082529e2302157..e2605b26100794581353d404c9d781caf657149b 100644
--- a/frontend/src/metabase/components/AdminLayout.jsx
+++ b/frontend/src/metabase/components/AdminLayout.jsx
@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 
-import AdminHeader from "./AdminHeader.jsx";
+import AdminHeader from "./AdminHeader";
 
 export default class AdminLayout extends Component {
   setSaving = () => {
diff --git a/frontend/src/metabase/components/Alert.jsx b/frontend/src/metabase/components/Alert.jsx
index e92a516c737af3c49ff9ffb025a6a826fc903117..2b646d075b09543cf21a49a58f7c62558dfc4cdc 100644
--- a/frontend/src/metabase/components/Alert.jsx
+++ b/frontend/src/metabase/components/Alert.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 import { t } from "ttag";
-import Modal from "metabase/components/Modal.jsx";
+import Modal from "metabase/components/Modal";
 
 const Alert = ({ message, onClose }) => (
   <Modal small isOpen={!!message}>
diff --git a/frontend/src/metabase/components/ArchivedItem.jsx b/frontend/src/metabase/components/ArchivedItem.jsx
index 4be734da9ff40b18d70bac2ecf07da6cc07a97d6..4773be74b157f99693397ea618ac5cd2e0a658a2 100644
--- a/frontend/src/metabase/components/ArchivedItem.jsx
+++ b/frontend/src/metabase/components/ArchivedItem.jsx
@@ -4,19 +4,19 @@ import React from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 
-import CheckBox from "metabase/components/CheckBox.jsx";
+import CheckBox from "metabase/components/CheckBox";
 import Icon from "metabase/components/Icon";
 import IconWrapper from "metabase/components/IconWrapper";
 import Swapper from "metabase/components/Swapper";
 import Tooltip from "metabase/components/Tooltip";
 
-import colors from "metabase/lib/colors";
+import { color as c } from "metabase/lib/colors";
 
 const ArchivedItem = ({
   name,
   type,
   icon,
-  color = colors["text-light"],
+  color = c("text-light"),
   isAdmin = false,
   onUnarchive,
   onDelete,
diff --git a/frontend/src/metabase/components/Breadcrumbs.jsx b/frontend/src/metabase/components/Breadcrumbs.jsx
index 0924d7a31f76596191d706c4a28e632d8b62c0d0..51548fd2ee8acfcf3061fead7b12b36433434740 100644
--- a/frontend/src/metabase/components/Breadcrumbs.jsx
+++ b/frontend/src/metabase/components/Breadcrumbs.jsx
@@ -4,8 +4,8 @@ import { Link } from "react-router";
 
 import S from "./Breadcrumbs.css";
 
-import Icon from "metabase/components/Icon.jsx";
-import Ellipsified from "metabase/components/Ellipsified.jsx";
+import Icon from "metabase/components/Icon";
+import Ellipsified from "metabase/components/Ellipsified";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/components/BrowserCrumbs.jsx b/frontend/src/metabase/components/BrowserCrumbs.jsx
index eede9117497b79d6292bfad1e4d91d3f13be3786..5b351a6a668f09c8ecfb8cc68924a27e0af530e0 100644
--- a/frontend/src/metabase/components/BrowserCrumbs.jsx
+++ b/frontend/src/metabase/components/BrowserCrumbs.jsx
@@ -3,7 +3,7 @@ import { Flex } from "grid-styled";
 import Icon from "metabase/components/Icon";
 import Link from "metabase/components/Link";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 // TODO: merge with Breadcrumbs
 
@@ -35,7 +35,7 @@ const BrowserCrumbs = ({ crumbs, analyticsContext }) => (
             <Icon
               key={"divider" + index}
               name="chevronright"
-              color={colors["text-light"]}
+              color={color("text-light")}
               mx={1}
             />
           ) : null}
diff --git a/frontend/src/metabase/components/Button.jsx b/frontend/src/metabase/components/Button.jsx
index f0f91e593b2524b04120aea527e874374eacd5f5..4ea0fe0a51538ce95413a8e38b39bba07c67e3cb 100644
--- a/frontend/src/metabase/components/Button.jsx
+++ b/frontend/src/metabase/components/Button.jsx
@@ -2,7 +2,7 @@ import React from "react";
 import PropTypes from "prop-types";
 import sys from "system-components";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 import cx from "classnames";
 import _ from "underscore";
 
diff --git a/frontend/src/metabase/components/Card.jsx b/frontend/src/metabase/components/Card.jsx
index 10aded46d1e91a8ea75a429b16c6a02c86c82f7b..63e0db6e3cde2013a8288148b5a59b28725261da 100644
--- a/frontend/src/metabase/components/Card.jsx
+++ b/frontend/src/metabase/components/Card.jsx
@@ -1,22 +1,22 @@
 import styled from "styled-components";
 import { space, width } from "styled-system";
-import colors, { alpha } from "metabase/lib/colors";
+import { color, alpha } from "metabase/lib/colors";
 
 const Card = styled.div`
   ${width}
   ${space}
-  background-color: ${props => (props.dark ? colors["text-dark"] : "white")};
+  background-color: ${props => (props.dark ? color("text-dark") : "white")};
   border: 1px solid ${props =>
-    props.dark ? "transparent" : colors["bg-medium"]};
+    props.dark ? "transparent" : color("bg-medium")};
   ${props => props.dark && `color: white`};
   border-radius: 6px;
-  box-shadow: 0 7px 20px ${props => colors["shadow"]};
+  box-shadow: 0 7px 20px ${props => color("shadow")};
   transition: all 0.2s linear;
   line-height: 24px;
   ${props =>
     props.hoverable &&
     `&:hover {
-    box-shadow: 0 10px 22px ${alpha(colors["shadow"], 0.09)};
+    box-shadow: 0 10px 22px ${alpha(color("shadow"), 0.09)};
   }`};
 `;
 
diff --git a/frontend/src/metabase/components/ChannelSetupModal.jsx b/frontend/src/metabase/components/ChannelSetupModal.jsx
index bc399a6fb0c540f0157ad1639e587ae5b4d354fa..37e860d125e9f8a260dd835ca3b3b4bece7d4e73 100644
--- a/frontend/src/metabase/components/ChannelSetupModal.jsx
+++ b/frontend/src/metabase/components/ChannelSetupModal.jsx
@@ -3,7 +3,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
 import { t } from "ttag";
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalContent from "metabase/components/ModalContent";
 import ChannelSetupMessage from "metabase/components/ChannelSetupMessage";
 
 export default class ChannelSetupModal extends Component {
diff --git a/frontend/src/metabase/components/CheckBox.jsx b/frontend/src/metabase/components/CheckBox.jsx
index dc60c49aea77af46e3be45a58c46dd0ed9bb1a61..c9dcff158c37642a35ab35c86d7399ea1a549cca 100644
--- a/frontend/src/metabase/components/CheckBox.jsx
+++ b/frontend/src/metabase/components/CheckBox.jsx
@@ -4,7 +4,7 @@ import cx from "classnames";
 
 import Icon from "metabase/components/Icon";
 
-import colors, { normal as defaultColors } from "metabase/lib/colors";
+import { color as c, normal as defaultColors } from "metabase/lib/colors";
 
 export default class CheckBox extends Component {
   static propTypes = {
@@ -48,7 +48,7 @@ export default class CheckBox extends Component {
     } = this.props;
 
     const checkedColor = defaultColors[color];
-    const uncheckedColor = colors["text-light"];
+    const uncheckedColor = c("text-light");
 
     const checkboxStyle = {
       width: size,
diff --git a/frontend/src/metabase/components/CollectionItem.jsx b/frontend/src/metabase/components/CollectionItem.jsx
index 00c06dd72a0844c0fb33fbfcf5879ac7f142c40e..9ac4e1a4a72ca1d83de72f9ff8e18ac421d49f3b 100644
--- a/frontend/src/metabase/components/CollectionItem.jsx
+++ b/frontend/src/metabase/components/CollectionItem.jsx
@@ -6,27 +6,27 @@ import Ellipsified from "metabase/components/Ellipsified";
 import Icon from "metabase/components/Icon";
 import Link from "metabase/components/Link";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const ItemLink = props => (
   <Link
     to={`collection/${props.collection.id}`}
     bg={
       props.hovered
-        ? colors["brand"]
+        ? color("brand")
         : props.highlighted
-        ? colors["bg-light"]
-        : colors["bg-medium"]
+        ? color("bg-light")
+        : color("bg-medium")
     }
-    color={props.hovered ? "white" : colors["text-medium"]}
+    color={props.hovered ? "white" : color("text-medium")}
     className="block rounded relative text-brand-hover"
     data-metabase-event={props.event}
     style={{
       borderSize: 1,
       borderColor: props.hovered
-        ? colors["brand"]
+        ? color("brand")
         : props.highlighted
-        ? colors["bg-medium"]
+        ? color("bg-medium")
         : "transparent",
       borderStyle: props.hovered
         ? "solid"
@@ -34,7 +34,7 @@ const ItemLink = props => (
         ? "dotted"
         : "solid",
     }}
-    hover={{ color: colors["brand"] }}
+    hover={{ color: color("brand") }}
   >
     {props.children}
   </Link>
@@ -51,7 +51,7 @@ const CollectionItem = props => {
     <Icon
       name={props.iconName}
       mx={props.asCard ? 0 : 1}
-      color={props.asCard ? "white" : colors["bg-dark"]}
+      color={props.asCard ? "white" : color("bg-dark")}
     />
   );
 
@@ -67,7 +67,7 @@ const CollectionItem = props => {
           align="center"
           justify="center"
           w="42px"
-          bg={colors["bg-dark"]}
+          bg={color("bg-dark")}
           style={{ height: 42, borderRadius: 6, flexShrink: 0 }}
           mr={1}
         >
diff --git a/frontend/src/metabase/components/CollectionLanding.jsx b/frontend/src/metabase/components/CollectionLanding.jsx
index f71b47cfb2171a6927e2d408d95cc03e027a7fc3..f6523a8bb6a9a6b80d20bd7535e5dc9c560b1fa5 100644
--- a/frontend/src/metabase/components/CollectionLanding.jsx
+++ b/frontend/src/metabase/components/CollectionLanding.jsx
@@ -16,7 +16,7 @@ import listSelect from "metabase/hoc/ListSelect";
 import BulkActionBar from "metabase/components/BulkActionBar";
 
 import * as Urls from "metabase/lib/urls";
-import colors, { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import Button from "metabase/components/Button";
 import Card from "metabase/components/Card";
@@ -217,7 +217,7 @@ class DefaultLanding extends React.Component {
             pt={2}
             pb={3}
             px={4}
-            bg={pinned.length ? colors["bg-medium"] : null}
+            bg={pinned.length ? color("bg-medium") : null}
           >
             <Box>
               <Box mb={1}>
@@ -245,8 +245,8 @@ class DefaultLanding extends React.Component {
                       name="info"
                       ml={1}
                       mt="4px"
-                      color={colors["bg-dark"]}
-                      hover={{ color: colors["brand"] }}
+                      color={color("bg-dark")}
+                      hover={{ color: color("brand") }}
                     />
                   </Tooltip>
                 )}
@@ -282,7 +282,7 @@ class DefaultLanding extends React.Component {
           <Box>
             <Box>
               {collectionHasPins ? (
-                <Box px={PAGE_PADDING} pt={2} pb={3} bg={colors["bg-medium"]}>
+                <Box px={PAGE_PADDING} pt={2} pb={3} bg={color("bg-medium")}>
                   <CollectionSectionHeading>{t`Pins`}</CollectionSectionHeading>
                   <PinDropTarget
                     pinIndex={pinned[pinned.length - 1].collection_position + 1}
@@ -447,9 +447,7 @@ class DefaultLanding extends React.Component {
                         justify="center"
                         py={2}
                         m={2}
-                        color={
-                          hovered ? colors["brand"] : colors["text-medium"]
-                        }
+                        color={hovered ? color("brand") : color("text-medium")}
                       >
                         {t`Drag here to un-pin`}
                       </Flex>
@@ -582,7 +580,7 @@ const PinnedItem = ({ item, index, collection }) => (
   <Link
     to={item.getUrl()}
     className="hover-parent hover--visibility"
-    hover={{ color: normal.blue }}
+    hover={{ color: color("brand") }}
     data-metabase-event={`${ANALYTICS_CONTEXT};Pinned Item;Click;${item.model}`}
   >
     <Card hoverable p={3}>
@@ -678,7 +676,7 @@ class CollectionLanding extends React.Component {
 const CollectionSectionHeading = ({ children }) => (
   <h5
     className="text-uppercase"
-    style={{ color: colors["text-medium"], fontWeight: 900 }}
+    style={{ color: color("text-medium"), fontWeight: 900 }}
   >
     {children}
   </h5>
diff --git a/frontend/src/metabase/components/CollectionList.jsx b/frontend/src/metabase/components/CollectionList.jsx
index 1cd150cad464c28313d42f92e4be7befe3601f08..d2c5c7b3ac02572ee65c4333edb7d88cb8900413 100644
--- a/frontend/src/metabase/components/CollectionList.jsx
+++ b/frontend/src/metabase/components/CollectionList.jsx
@@ -6,7 +6,7 @@ import { connect } from "react-redux";
 import * as Urls from "metabase/lib/urls";
 
 import CollectionItem from "metabase/components/CollectionItem";
-import { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import { Grid, GridItem } from "metabase/components/Grid";
 import Icon from "metabase/components/Icon";
 import Link from "metabase/components/Link";
@@ -97,8 +97,8 @@ class CollectionList extends React.Component {
             <GridItem w={w}>
               <Link
                 to={Urls.newCollection(currentCollection.id)}
-                color={normal.grey2}
-                hover={{ color: normal.blue }}
+                color={color("text-medium")}
+                hover={{ color: color("brand") }}
                 p={w === 1 ? [1, 2] : 0}
                 data-metabase-event={`${analyticsContext};Collection List; New Collection Click`}
               >
diff --git a/frontend/src/metabase/components/ColumnarSelector.jsx b/frontend/src/metabase/components/ColumnarSelector.jsx
index 67f4b2b885941f36ea91b0f4052e82edc1ce231a..d8b7e6665449e9541501a943b08598a8e6277911 100644
--- a/frontend/src/metabase/components/ColumnarSelector.jsx
+++ b/frontend/src/metabase/components/ColumnarSelector.jsx
@@ -3,7 +3,7 @@ import PropTypes from "prop-types";
 
 import "./ColumnarSelector.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/components/Confirm.jsx b/frontend/src/metabase/components/Confirm.jsx
index 843c4683ea16ea88ea8ab8162280bce36f5ddafe..fbb3cdeb10721485485951ee82aa64707784ed05 100644
--- a/frontend/src/metabase/components/Confirm.jsx
+++ b/frontend/src/metabase/components/Confirm.jsx
@@ -2,8 +2,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
-import ConfirmContent from "./ConfirmContent.jsx";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
+import ConfirmContent from "./ConfirmContent";
 
 export default class Confirm extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/components/ConfirmContent.jsx b/frontend/src/metabase/components/ConfirmContent.jsx
index 13852bdc46f7e33dd7ab4246b6210a2f389bff36..681b5a22182375af5472812901aa43c89c5d1745 100644
--- a/frontend/src/metabase/components/ConfirmContent.jsx
+++ b/frontend/src/metabase/components/ConfirmContent.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalContent from "metabase/components/ModalContent";
 import { t } from "ttag";
 
 import Button from "metabase/components/Button";
diff --git a/frontend/src/metabase/components/DatabaseDetailsForm.jsx b/frontend/src/metabase/components/DatabaseDetailsForm.jsx
index 38b29d13636c141846a4ff6bf1c6f992714880e9..b79a9ac54103c340238caf0a24a93a16368bbfee 100644
--- a/frontend/src/metabase/components/DatabaseDetailsForm.jsx
+++ b/frontend/src/metabase/components/DatabaseDetailsForm.jsx
@@ -2,10 +2,10 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
 import { t, jt } from "ttag";
-import FormField from "metabase/components/form/FormField.jsx";
-import FormLabel from "metabase/components/form/FormLabel.jsx";
-import FormMessage from "metabase/components/form/FormMessage.jsx";
-import Toggle from "metabase/components/Toggle.jsx";
+import FormField from "metabase/components/form/FormField";
+import FormLabel from "metabase/components/form/FormLabel";
+import FormMessage from "metabase/components/form/FormMessage";
+import Toggle from "metabase/components/Toggle";
 
 import { shallowEqual } from "recompose";
 
@@ -57,10 +57,10 @@ export default class DatabaseDetailsForm extends Component {
     engines: PropTypes.object.isRequired,
     formError: PropTypes.object,
     hiddenFields: PropTypes.object,
-    isNewDatabase: PropTypes.boolean,
+    isNewDatabase: PropTypes.bool,
     submitButtonText: PropTypes.string.isRequired,
     submitFn: PropTypes.func.isRequired,
-    submitting: PropTypes.boolean,
+    submitting: PropTypes.bool,
   };
 
   validateForm() {
@@ -196,7 +196,7 @@ export default class DatabaseDetailsForm extends Component {
   }
 
   renderField(field, fieldIndex) {
-    const { engine } = this.props;
+    const { engine, formError } = this.props;
     const { details } = this.state;
     window.ENGINE = engine;
 
@@ -415,8 +415,16 @@ export default class DatabaseDetailsForm extends Component {
       );
     } else {
       return (
-        <FormField key={field.name} fieldName={field.name}>
-          <FormLabel title={field["display-name"]} fieldName={field.name} />
+        <FormField
+          key={field.name}
+          fieldName={field.name}
+          formError={formError}
+        >
+          <FormLabel
+            title={field["display-name"]}
+            fieldName={field.name}
+            formError={formError}
+          />
           {this.renderFieldInput(field, fieldIndex)}
           <span className="Form-charm" />
         </FormField>
@@ -460,6 +468,19 @@ export default class DatabaseDetailsForm extends Component {
 
     hiddenFields = hiddenFields || {};
 
+    if (formError && formError.data) {
+      // If we have a field error but no matching field, use that field error as
+      // a fallback for formError.data.message
+      const { message, errors = {} } = formError.data;
+      const fieldNames = new Set(fields.map(field => field.name));
+      const [unusedFieldKey] = Object.keys(errors).filter(
+        name => !fieldNames.has(name),
+      );
+      if (unusedFieldKey && !message) {
+        formError.data.message = errors[unusedFieldKey];
+      }
+    }
+
     return (
       <form onSubmit={this.formSubmitted.bind(this)} noValidate>
         <div className="FormInputGroup pb2">
diff --git a/frontend/src/metabase/components/DeleteModalWithConfirm.jsx b/frontend/src/metabase/components/DeleteModalWithConfirm.jsx
index c82a04132294f9d79ce617bc38b3c95e277da025..203f08dbfe263cb7f6c2e1209b17eb24c2254a7e 100644
--- a/frontend/src/metabase/components/DeleteModalWithConfirm.jsx
+++ b/frontend/src/metabase/components/DeleteModalWithConfirm.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import ModalContent from "metabase/components/ModalContent.jsx";
-import CheckBox from "metabase/components/CheckBox.jsx";
+import ModalContent from "metabase/components/ModalContent";
+import CheckBox from "metabase/components/CheckBox";
 import { t } from "ttag";
 import cx from "classnames";
 import _ from "underscore";
diff --git a/frontend/src/metabase/components/DirectionalButton.jsx b/frontend/src/metabase/components/DirectionalButton.jsx
index 61f3ab05ee8d3216dff70693d3c7cc6108845d45..6d9fcb24e8213974c10b7c517721495b21a4526e 100644
--- a/frontend/src/metabase/components/DirectionalButton.jsx
+++ b/frontend/src/metabase/components/DirectionalButton.jsx
@@ -1,15 +1,15 @@
 import React from "react";
 import Icon from "metabase/components/Icon";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const DirectionalButton = ({ direction = "back", onClick }) => (
   <div
     className="shadowed cursor-pointer text-brand-hover text-medium flex align-center circle p2 bg-white transition-background transition-color"
     onClick={onClick}
     style={{
-      border: `1px solid ${colors["border"]}`,
-      boxShadow: `0 2px 4px 0 ${colors["shadow"]}`,
+      border: `1px solid ${color("border")}`,
+      boxShadow: `0 2px 4px 0 ${color("shadow")}`,
     }}
   >
     <Icon name={`arrow_${direction}`} />
diff --git a/frontend/src/metabase/components/DownloadButton.jsx b/frontend/src/metabase/components/DownloadButton.jsx
index 54ce9421e0ae5d9aa8e05c8f82a41490fb3e84b6..3c9f9b8798612b1700114434c2e810ad732a8fbb 100644
--- a/frontend/src/metabase/components/DownloadButton.jsx
+++ b/frontend/src/metabase/components/DownloadButton.jsx
@@ -2,7 +2,7 @@ import React from "react";
 import PropTypes from "prop-types";
 import { Box, Flex } from "grid-styled";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import { extractQueryParams } from "metabase/lib/urls";
 
 import Icon from "metabase/components/Icon";
@@ -11,13 +11,13 @@ import Text from "metabase/components/Text";
 function colorForType(type) {
   switch (type) {
     case "csv":
-      return colors["accent7"];
+      return color("accent7");
     case "xlsx":
-      return colors["accent1"];
+      return color("accent1");
     case "json":
-      return colors["bg-dark"];
+      return color("bg-dark");
     default:
-      return colors["brand"];
+      return color("brand");
   }
 }
 
diff --git a/frontend/src/metabase/components/EntityItem.jsx b/frontend/src/metabase/components/EntityItem.jsx
index 0c3e04bd3d83a8463fb8fc4175f2da566fb71463..29f21b6f5d0800868677f4b76b25393f3a3e842a 100644
--- a/frontend/src/metabase/components/EntityItem.jsx
+++ b/frontend/src/metabase/components/EntityItem.jsx
@@ -10,14 +10,14 @@ import CheckBox from "metabase/components/CheckBox";
 import Ellipsified from "metabase/components/Ellipsified";
 import Icon from "metabase/components/Icon";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const EntityItemWrapper = Flex.extend`
-  border-bottom: 1px solid ${colors["bg-medium"]};
+  border-bottom: 1px solid ${color("bg-medium")};
   /* TODO - figure out how to use the prop instead of this? */
   align-items: center;
   &:hover {
-    color: ${colors["brand"]};
+    color: ${color("brand")};
   }
 `;
 
diff --git a/frontend/src/metabase/components/EntityLayout.js b/frontend/src/metabase/components/EntityLayout.js
index af41b3dab7250814a48b8a1af409af73bd0b4f48..18d76249cfb61ad624b0333c8eb704e960fe5098 100644
--- a/frontend/src/metabase/components/EntityLayout.js
+++ b/frontend/src/metabase/components/EntityLayout.js
@@ -2,7 +2,7 @@ import React from "react";
 import { Box, Flex } from "grid-styled";
 import Subhead from "metabase/components/Subhead";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export const Wrapper = ({ children }) => (
   <Box w="80%" ml="auto" mr="auto">
@@ -12,11 +12,11 @@ export const Wrapper = ({ children }) => (
 
 export const Canvas = ({ children }) => (
   <Box
-    bg={colors["bg-white"]}
+    bg={color("bg-white")}
     p={2}
     style={{
-      borderTop: colors["border"],
-      borderBottom: colors["border"],
+      borderTop: color("border"),
+      borderBottom: color("border"),
     }}
   >
     {children}
diff --git a/frontend/src/metabase/components/EntityMenuItem.jsx b/frontend/src/metabase/components/EntityMenuItem.jsx
index cfd75cdbaa426c63ae77a3598579bf8f1d36bebb..079a4afeb87b0d20a455a7529c6e5a8dee7f2015 100644
--- a/frontend/src/metabase/components/EntityMenuItem.jsx
+++ b/frontend/src/metabase/components/EntityMenuItem.jsx
@@ -4,25 +4,25 @@ import { Link } from "react-router";
 
 import Icon from "metabase/components/Icon";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const Item = styled.div`
   display: flex;
   align-items: center;
   cursor: pointer;
-  color: ${colors["text-medium"]};
+  color: ${color("text-medium")};
   padding: 0.85em 1.45em;
   text-decoration: none;
   transition: all 300ms linear;
   :hover {
-    color: ${colors["brand"]};
+    color: ${color("brand")};
   }
   > .Icon {
-    color: ${colors["text-light"]};
+    color: ${color("text-light")};
     margin-right: 0.65em;
   }
   :hover > .Icon {
-    color: ${colors["brand"]};
+    color: ${color("brand")};
     transition: all 300ms linear;
   },
   /* icon specific tweaks
diff --git a/frontend/src/metabase/components/EntityPage.jsx b/frontend/src/metabase/components/EntityPage.jsx
index 3a15c0ed5184d9696bed7a17fe703cb491a5a627..fb79dde5de26df327dc088a1c590ce42f4db9241 100644
--- a/frontend/src/metabase/components/EntityPage.jsx
+++ b/frontend/src/metabase/components/EntityPage.jsx
@@ -13,7 +13,7 @@ import QuestionAndResultLoader from "metabase/containers/QuestionAndResultLoader
 
 import RelatedItems from "metabase/components/RelatedItems";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 class EntityPage extends Component {
   render() {
@@ -34,7 +34,7 @@ class EntityPage extends Component {
             <div key="entity">
               <Box
                 className="border-bottom hover-parent hover--visibility relative"
-                style={{ backgroundColor: colors["bg-white"], height: "65vh" }}
+                style={{ backgroundColor: color("bg-white"), height: "65vh" }}
               >
                 <Box className="hover-child absolute top right">
                   {!loading && (
@@ -68,7 +68,7 @@ class EntityPage extends Component {
                         p={2}
                         mt={4}
                         style={{
-                          border: `1px solid ${colors["border"]}`,
+                          border: `1px solid ${color("border")}`,
                           borderRadius: 6,
                         }}
                       >
diff --git a/frontend/src/metabase/components/ExplorePane.jsx b/frontend/src/metabase/components/ExplorePane.jsx
index 092e8f825e2a3c6f9f9472288bb6bc9f6806877e..42a0eceb33e7156c4703824d2227a4d2fa3eaf45 100644
--- a/frontend/src/metabase/components/ExplorePane.jsx
+++ b/frontend/src/metabase/components/ExplorePane.jsx
@@ -9,7 +9,7 @@ import Select, { Option } from "metabase/components/Select";
 import { Grid, GridItem } from "metabase/components/Grid";
 import Card from "metabase/components/Card";
 import { Flex } from "grid-styled";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import { t } from "ttag";
 import _ from "underscore";
@@ -162,7 +162,7 @@ export const ExploreOption = ({ option }: { option: Candidate }) => (
     <Flex
       align="center"
       justify="center"
-      bg={colors["accent4"]}
+      bg={color("accent4")}
       w="42px"
       style={{ borderRadius: 6, height: 42 }}
       mr={1}
diff --git a/frontend/src/metabase/components/Header.jsx b/frontend/src/metabase/components/Header.jsx
index 76d3f9eca9f7a9f7339043a5c88c624030a042de..4b5f438496470291c3c1b999585f33f56b92296c 100644
--- a/frontend/src/metabase/components/Header.jsx
+++ b/frontend/src/metabase/components/Header.jsx
@@ -2,10 +2,10 @@ import React, { Component } from "react";
 import ReactDOM from "react-dom";
 
 import CollectionBadge from "metabase/questions/components/CollectionBadge";
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
-import HeaderModal from "metabase/components/HeaderModal.jsx";
-import TitleAndDescription from "metabase/components/TitleAndDescription.jsx";
-import EditBar from "metabase/components/EditBar.jsx";
+import InputBlurChange from "metabase/components/InputBlurChange";
+import HeaderModal from "metabase/components/HeaderModal";
+import TitleAndDescription from "metabase/components/TitleAndDescription";
+import EditBar from "metabase/components/EditBar";
 import { t } from "ttag";
 import { getScrollY } from "metabase/lib/dom";
 
diff --git a/frontend/src/metabase/components/HistoryModal.jsx b/frontend/src/metabase/components/HistoryModal.jsx
index c6085581d9289711681445ce88f3d261ef07e7d1..93b42d40d83652542fb78952c8732832db1ecd83 100644
--- a/frontend/src/metabase/components/HistoryModal.jsx
+++ b/frontend/src/metabase/components/HistoryModal.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import ActionButton from "metabase/components/ActionButton.jsx";
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ActionButton from "metabase/components/ActionButton";
+import ModalContent from "metabase/components/ModalContent";
 
 import moment from "moment";
 
diff --git a/frontend/src/metabase/components/Icon.jsx b/frontend/src/metabase/components/Icon.jsx
index 00d02a9df73d90be22e442c89f34893255e50a27..a90a88ec8a1a590383116f7ad85ed55dfb889c65 100644
--- a/frontend/src/metabase/components/Icon.jsx
+++ b/frontend/src/metabase/components/Icon.jsx
@@ -5,7 +5,7 @@ import RetinaImage from "react-retina-image";
 import styled from "styled-components";
 import { color, space, hover } from "styled-system";
 import cx from "classnames";
-import colors from "metabase/lib/colors";
+import { color as c } from "metabase/lib/colors";
 
 import { loadIcon } from "metabase/icon_paths";
 import { stripLayoutProps } from "metabase/lib/utils";
@@ -21,7 +21,7 @@ export const IconWrapper = styled("div")`
   height: 40px;
   border-radius: 99px;
   cursor: pointer;
-  color: ${props => (props.open ? colors["brand"] : "inherit")};
+  color: ${props => (props.open ? c("brand") : "inherit")};
   // special cases for certain icons
   // Icon-share has a taller viewvbox than most so to optically center
   // the icon we need to translate it upwards
@@ -34,8 +34,8 @@ export const IconWrapper = styled("div")`
 
 IconWrapper.defaultProps = {
   hover: {
-    backgroundColor: colors["bg-medium"],
-    color: colors["brand"],
+    backgroundColor: c("bg-medium"),
+    color: c("brand"),
   },
 };
 
diff --git a/frontend/src/metabase/components/IconWrapper.jsx b/frontend/src/metabase/components/IconWrapper.jsx
index 5deb01190c3255c5a2317ce3c1f0ac6a6daff805..f8d9b11bc5927bf82e0e4fc36673a1d41af688e4 100644
--- a/frontend/src/metabase/components/IconWrapper.jsx
+++ b/frontend/src/metabase/components/IconWrapper.jsx
@@ -1,8 +1,8 @@
 import { Flex } from "grid-styled";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const IconWrapper = Flex.extend`
-  background: ${colors["bg-medium"]};
+  background: ${color("bg-medium")};
   border-radius: 6px;
 `;
 
diff --git a/frontend/src/metabase/components/ItemTypeFilterBar.jsx b/frontend/src/metabase/components/ItemTypeFilterBar.jsx
index 8c03b7fe5f17703afc580413ddd1d09f80cc7025..96c64f5b5de7388a862e512590980722d846bfa2 100644
--- a/frontend/src/metabase/components/ItemTypeFilterBar.jsx
+++ b/frontend/src/metabase/components/ItemTypeFilterBar.jsx
@@ -6,7 +6,7 @@ import { withRouter } from "react-router";
 import Icon from "metabase/components/Icon";
 import Link from "metabase/components/Link";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export const FILTERS = [
   {
@@ -42,7 +42,7 @@ const ItemTypeFilterBar = props => {
           isActive = true;
         }
 
-        const color = isActive ? colors.brand : "inherit";
+        const linkColor = isActive ? color("brand") : "inherit";
 
         return (
           <Link
@@ -50,8 +50,8 @@ const ItemTypeFilterBar = props => {
               pathname: location.pathname,
               query: { ...location.query, type: f.filter },
             }}
-            color={color}
-            hover={{ color: colors.brand }}
+            color={linkColor}
+            hover={{ color: color("brand") }}
             className="flex-full flex align-center justify-center sm-block text-brand-hover text-medium"
             mr={[0, 2]}
             key={f.filter}
@@ -59,7 +59,7 @@ const ItemTypeFilterBar = props => {
             data-metabase-event={`${analyticsContext};Item Filter;${f.name}`}
             style={{
               borderBottom: `2px solid ${
-                isActive ? colors.brand : "transparent"
+                isActive ? color("brand") : "transparent"
               }`,
             }}
           >
@@ -67,7 +67,7 @@ const ItemTypeFilterBar = props => {
             <h5
               className="text-uppercase hide sm-show"
               style={{
-                color: isActive ? colors.brand : "inherit",
+                color: isActive ? color("brand") : "inherit",
                 fontWeight: 900,
               }}
             >
diff --git a/frontend/src/metabase/components/LabelIcon.jsx b/frontend/src/metabase/components/LabelIcon.jsx
index a6a145c60948bb8e6dea7c5b5c16a6cb5dbdd139..e5b0f5eefbaf1a4650106ba763967c0843a70a19 100644
--- a/frontend/src/metabase/components/LabelIcon.jsx
+++ b/frontend/src/metabase/components/LabelIcon.jsx
@@ -4,7 +4,7 @@ import PropTypes from "prop-types";
 
 import S from "./LabelIcon.css";
 
-import Icon from "./Icon.jsx";
+import Icon from "./Icon";
 import cx from "classnames";
 
 const LabelIcon = ({ icon, size = 18, className, style }) =>
diff --git a/frontend/src/metabase/components/ListItem.jsx b/frontend/src/metabase/components/ListItem.jsx
index bbd0c1f20f98941890fe660b89410f89122306d2..b0fd19885a5f5b1c09d05ce41065db6441faed60 100644
--- a/frontend/src/metabase/components/ListItem.jsx
+++ b/frontend/src/metabase/components/ListItem.jsx
@@ -4,8 +4,8 @@ import PropTypes from "prop-types";
 import { Link } from "react-router";
 import S from "./List.css";
 import { t } from "ttag";
-import Icon from "./Icon.jsx";
-import Ellipsified from "./Ellipsified.jsx";
+import Icon from "./Icon";
+import Ellipsified from "./Ellipsified";
 
 import cx from "classnames";
 import pure from "recompose/pure";
diff --git a/frontend/src/metabase/components/LoadingAndErrorWrapper.jsx b/frontend/src/metabase/components/LoadingAndErrorWrapper.jsx
index b2f90f8dfa9bab61665512c5956e123dbca3ed74..af08de469634631a948ca226dfffd6ea5329ecec 100644
--- a/frontend/src/metabase/components/LoadingAndErrorWrapper.jsx
+++ b/frontend/src/metabase/components/LoadingAndErrorWrapper.jsx
@@ -2,7 +2,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
 import { t } from "ttag";
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/components/Modal.jsx b/frontend/src/metabase/components/Modal.jsx
index a024d83ce863f433db623bb0ca4aad9290d0d032..b5532589fb5c6d6cf3382d7452f603d2457a1415 100644
--- a/frontend/src/metabase/components/Modal.jsx
+++ b/frontend/src/metabase/components/Modal.jsx
@@ -8,7 +8,7 @@ import { getScrollX, getScrollY } from "metabase/lib/dom";
 import { CSSTransitionGroup } from "react-transition-group";
 import { Motion, spring } from "react-motion";
 
-import OnClickOutsideWrapper from "./OnClickOutsideWrapper.jsx";
+import OnClickOutsideWrapper from "./OnClickOutsideWrapper";
 import ModalContent from "./ModalContent";
 
 import _ from "underscore";
diff --git a/frontend/src/metabase/components/ModalContent.jsx b/frontend/src/metabase/components/ModalContent.jsx
index ecefdbd1b2531fba520b98d8eea4d1f411f6ca8f..a44c955f0802d135d463612e0be5c2d1af6baa47 100644
--- a/frontend/src/metabase/components/ModalContent.jsx
+++ b/frontend/src/metabase/components/ModalContent.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 export default class ModalContent extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/components/ModalWithTrigger.jsx b/frontend/src/metabase/components/ModalWithTrigger.jsx
index fd89cf9df6ef4cbd55dc41268fb32e44127901bf..0f60abb794640c5ad8ff882caa996ecb8a5577d0 100644
--- a/frontend/src/metabase/components/ModalWithTrigger.jsx
+++ b/frontend/src/metabase/components/ModalWithTrigger.jsx
@@ -1,4 +1,4 @@
-import Triggerable from "./Triggerable.jsx";
-import Modal from "./Modal.jsx";
+import Triggerable from "./Triggerable";
+import Modal from "./Modal";
 
 export default Triggerable(Modal);
diff --git a/frontend/src/metabase/components/NewsletterForm.jsx b/frontend/src/metabase/components/NewsletterForm.jsx
index e8864ec4bfa742476d3062b1833caa9b0559a05b..5a9fce98eaa7c9cbb6825e5d8dbdce418034fdb9 100644
--- a/frontend/src/metabase/components/NewsletterForm.jsx
+++ b/frontend/src/metabase/components/NewsletterForm.jsx
@@ -3,8 +3,8 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import ReactDOM from "react-dom";
 import { t } from "ttag";
-import Icon from "metabase/components/Icon.jsx";
-import colors from "metabase/lib/colors";
+import Icon from "metabase/components/Icon";
+import { color } from "metabase/lib/colors";
 
 export default class NewsletterForm extends Component {
   constructor(props, context) {
@@ -19,7 +19,7 @@ export default class NewsletterForm extends Component {
 
       input: {
         fontSize: "1.1rem",
-        color: colors["text-dark"],
+        color: color("text-dark"),
         width: "350px",
       },
 
@@ -75,7 +75,7 @@ export default class NewsletterForm extends Component {
         <div className="MB-Newsletter sm-float-right">
           <div>
             <div
-              style={{ color: colors["text-medium"] }}
+              style={{ color: color("text-medium") }}
               className="text-medium h3 pb3"
             >
               {t`Get infrequent emails about new releases and feature updates.`}
diff --git a/frontend/src/metabase/components/NumericInput.jsx b/frontend/src/metabase/components/NumericInput.jsx
index d46ce4df601613d666acd161101c69bc05a864d6..87d3ce292ddc5469fe914d29a10ebaf5ac7b414c 100644
--- a/frontend/src/metabase/components/NumericInput.jsx
+++ b/frontend/src/metabase/components/NumericInput.jsx
@@ -2,7 +2,7 @@
 
 import React from "react";
 
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
+import InputBlurChange from "metabase/components/InputBlurChange";
 
 type Props = {
   value: ?(number | string),
diff --git a/frontend/src/metabase/components/PasswordReveal.jsx b/frontend/src/metabase/components/PasswordReveal.jsx
index 7bcb141a2269d0546323c38fe0e17988dd53163f..2a74e4c4f93a8101680c4e0cd2978bee6caac415 100644
--- a/frontend/src/metabase/components/PasswordReveal.jsx
+++ b/frontend/src/metabase/components/PasswordReveal.jsx
@@ -2,7 +2,7 @@
 import React, { Component } from "react";
 import CopyButton from "metabase/components/CopyButton";
 import { t } from "ttag";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 type State = {
   visible: boolean,
@@ -16,7 +16,7 @@ const styles = {
   input: {
     fontSize: "1.2rem",
     letterSpacing: "2",
-    color: colors["text-dark"],
+    color: color("text-dark"),
     outline: "none",
   },
 };
diff --git a/frontend/src/metabase/components/PopoverWithTrigger.jsx b/frontend/src/metabase/components/PopoverWithTrigger.jsx
index 8385d166964f2335bb14ae525bcbc187b64e7dba..3cc78915e5ae565f0a7f9e81413f2a327f18b621 100644
--- a/frontend/src/metabase/components/PopoverWithTrigger.jsx
+++ b/frontend/src/metabase/components/PopoverWithTrigger.jsx
@@ -1,4 +1,4 @@
-import Triggerable from "./Triggerable.jsx";
-import Popover from "./Popover.jsx";
+import Triggerable from "./Triggerable";
+import Popover from "./Popover";
 
 export default Triggerable(Popover);
diff --git a/frontend/src/metabase/components/ProgressBar.jsx b/frontend/src/metabase/components/ProgressBar.jsx
index 3a86939221f84f494f6dc9a625c891d03ed96378..0cc9694d3646dece0c6461016c0feeacc6a1383d 100644
--- a/frontend/src/metabase/components/ProgressBar.jsx
+++ b/frontend/src/metabase/components/ProgressBar.jsx
@@ -2,7 +2,7 @@
 import React, { Component } from "react";
 import styled from "styled-components";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 type Props = {
   percentage: number,
@@ -36,7 +36,7 @@ const Progress = styled.div`
         left: 0;
         width: ${props => props.width / 4}%;
         height: 100%;
-        background-color: ${colors["bg-black"]};
+        background-color: ${color("bg-black")};
         animation: ${props =>
           props.animated ? "progress-bar 1.5s linear infinite" : "none"};
       },
@@ -47,7 +47,7 @@ export default class ProgressBar extends Component {
 
   static defaultProps = {
     animated: false,
-    color: colors["brand"],
+    color: color("brand"),
     height: 10,
   };
 
diff --git a/frontend/src/metabase/components/QueryButton.jsx b/frontend/src/metabase/components/QueryButton.jsx
index 89320373a9b7318425ff696ae48746697cfe1ac1..d3f503129d0518b57fe55a154863deb2132eeb75 100644
--- a/frontend/src/metabase/components/QueryButton.jsx
+++ b/frontend/src/metabase/components/QueryButton.jsx
@@ -6,7 +6,7 @@ import cx from "classnames";
 
 import S from "./QueryButton.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const QueryButton = ({ className, text, icon, iconClass, onClick, link }) => (
   <div className={className}>
diff --git a/frontend/src/metabase/components/QuestionSavedModal.jsx b/frontend/src/metabase/components/QuestionSavedModal.jsx
index 2ea5d8b1ed94a7aecd79adf8edbafdafcc018487..901f08d7ccd6303541d717ac2d3a28934df4efc4 100644
--- a/frontend/src/metabase/components/QuestionSavedModal.jsx
+++ b/frontend/src/metabase/components/QuestionSavedModal.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalContent from "metabase/components/ModalContent";
 import { t } from "ttag";
 
 export default class QuestionSavedModal extends Component {
diff --git a/frontend/src/metabase/components/SaveStatus.jsx b/frontend/src/metabase/components/SaveStatus.jsx
index 91fc265b9b447789c50544078e5b7858f2e1ef3f..94701f4d98186cddac2384b16b6fa3d562c86182 100644
--- a/frontend/src/metabase/components/SaveStatus.jsx
+++ b/frontend/src/metabase/components/SaveStatus.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 
-import Icon from "metabase/components/Icon.jsx";
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
+import Icon from "metabase/components/Icon";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
 import { t } from "ttag";
 import _ from "underscore";
 
diff --git a/frontend/src/metabase/components/SchedulePicker.jsx b/frontend/src/metabase/components/SchedulePicker.jsx
index d9e0ab3257fde014ecb7fb0def1ab482c064e6e7..b6edf37d4ceb6336f13dde6735bf21ec8eec08a1 100644
--- a/frontend/src/metabase/components/SchedulePicker.jsx
+++ b/frontend/src/metabase/components/SchedulePicker.jsx
@@ -2,7 +2,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Select from "metabase/components/Select.jsx";
+import Select from "metabase/components/Select";
 
 import Settings from "metabase/lib/settings";
 import { capitalize } from "metabase/lib/formatting";
diff --git a/frontend/src/metabase/components/Select.jsx b/frontend/src/metabase/components/Select.jsx
index 6cd29e5a1df7d627b47673d9d1c3253fccf16330..248f1acb15578dc2733acdac9a567ebbcbba4002 100644
--- a/frontend/src/metabase/components/Select.jsx
+++ b/frontend/src/metabase/components/Select.jsx
@@ -5,9 +5,9 @@ import PropTypes from "prop-types";
 import { List } from "react-virtualized";
 import "react-virtualized/styles.css";
 import { t } from "ttag";
-import ColumnarSelector from "metabase/components/ColumnarSelector.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
+import ColumnarSelector from "metabase/components/ColumnarSelector";
+import Icon from "metabase/components/Icon";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
 import SelectButton from "./SelectButton";
 
 import cx from "classnames";
diff --git a/frontend/src/metabase/components/SelectButton.jsx b/frontend/src/metabase/components/SelectButton.jsx
index 20dd188605b3e5d69da61812d8e676dc7ec0de1a..4cbe34393703778919c92e0c58ec15feefc0b9f2 100644
--- a/frontend/src/metabase/components/SelectButton.jsx
+++ b/frontend/src/metabase/components/SelectButton.jsx
@@ -2,7 +2,7 @@
 import React from "react";
 import PropTypes from "prop-types";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/components/SidebarItem.jsx b/frontend/src/metabase/components/SidebarItem.jsx
index ff77101a75ea94cdc09c43f208779064a920be23..fb3684839388f878589ea93fab04586d8c9c68e6 100644
--- a/frontend/src/metabase/components/SidebarItem.jsx
+++ b/frontend/src/metabase/components/SidebarItem.jsx
@@ -4,7 +4,7 @@ import PropTypes from "prop-types";
 import { Link } from "react-router";
 import S from "./Sidebar.css";
 
-import LabelIcon from "./LabelIcon.jsx";
+import LabelIcon from "./LabelIcon";
 
 import pure from "recompose/pure";
 
diff --git a/frontend/src/metabase/components/StackedCheckBox.jsx b/frontend/src/metabase/components/StackedCheckBox.jsx
index cb5b34448021ad0386b201ef7c5d9f51e46c6a31..a227b5dc96df54ccd6a556d684e8173d25a570d6 100644
--- a/frontend/src/metabase/components/StackedCheckBox.jsx
+++ b/frontend/src/metabase/components/StackedCheckBox.jsx
@@ -1,7 +1,7 @@
 import React from "react";
 import cx from "classnames";
 
-import CheckBox from "metabase/components/CheckBox.jsx";
+import CheckBox from "metabase/components/CheckBox";
 
 const OFFSET = 4;
 
diff --git a/frontend/src/metabase/components/StepIndicators.jsx b/frontend/src/metabase/components/StepIndicators.jsx
index f705ef5886ebac73c6bd58717d5bbb732f80a30d..74c4dad7cba4ef08a4be1b70200b1e2a59fa8e9b 100644
--- a/frontend/src/metabase/components/StepIndicators.jsx
+++ b/frontend/src/metabase/components/StepIndicators.jsx
@@ -1,7 +1,7 @@
 /* @flow */
 import React from "react";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 type Props = {
   activeDotColor?: string,
@@ -12,7 +12,7 @@ type Props = {
 };
 
 const StepIndicators = ({
-  activeDotColor = colors["brand"],
+  activeDotColor = color("brand"),
   currentStep = 0,
   dotSize = 8,
   goToStep,
@@ -30,7 +30,7 @@ const StepIndicators = ({
           marginLeft: 2,
           marginRight: 2,
           backgroundColor:
-            index + 1 === currentStep ? activeDotColor : colors["text-light"],
+            index + 1 === currentStep ? activeDotColor : color("text-light"),
           transition: "background 600ms ease-in",
         }}
         key={index}
diff --git a/frontend/src/metabase/components/Text.jsx b/frontend/src/metabase/components/Text.jsx
index 6bc72e697ad1b409462570e255bc8ab3a165b709..c8089fd77235fc3c197025dfc04b30f2077e7add 100644
--- a/frontend/src/metabase/components/Text.jsx
+++ b/frontend/src/metabase/components/Text.jsx
@@ -1,10 +1,10 @@
 import styled from "styled-components";
 import { space } from "system-components";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const Text = styled.p`
   ${space};
-  color: ${props => colors[`text-${props.color}`]};
+  color: ${props => color(`text-${props.color}`)};
 `;
 
 Text.defaultProps = {
diff --git a/frontend/src/metabase/components/TitleAndDescription.jsx b/frontend/src/metabase/components/TitleAndDescription.jsx
index 28d86f33a38e84e547616529a8bd352de4dafe4b..2c16183e3e0a2ac263a9bdf193e6e88fd44aaaf6 100644
--- a/frontend/src/metabase/components/TitleAndDescription.jsx
+++ b/frontend/src/metabase/components/TitleAndDescription.jsx
@@ -3,8 +3,8 @@ import React from "react";
 import cx from "classnames";
 import pure from "recompose/pure";
 
-import Icon from "metabase/components/Icon.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import Icon from "metabase/components/Icon";
+import Tooltip from "metabase/components/Tooltip";
 
 type Attributes = {
   title: string,
diff --git a/frontend/src/metabase/components/Tooltip.jsx b/frontend/src/metabase/components/Tooltip.jsx
index 8d48042547b9773d1927996ffe3080af6c2ffdc0..cdb63bcdfc3ceadafd0a96901f39f1c550a0a698 100644
--- a/frontend/src/metabase/components/Tooltip.jsx
+++ b/frontend/src/metabase/components/Tooltip.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import ReactDOM from "react-dom";
 
-import TooltipPopover from "./TooltipPopover.jsx";
+import TooltipPopover from "./TooltipPopover";
 
 // TOOLTIP_STACK and related functions are to ensure only the most recent tooltip is visible
 
diff --git a/frontend/src/metabase/components/TooltipPopover.jsx b/frontend/src/metabase/components/TooltipPopover.jsx
index a437d5f1eb1dba35c28bb2592e7098a63333a8f4..9d0833c701da9a49b6947a756232e0c66f3b1d35 100644
--- a/frontend/src/metabase/components/TooltipPopover.jsx
+++ b/frontend/src/metabase/components/TooltipPopover.jsx
@@ -2,7 +2,7 @@ import React from "react";
 import cx from "classnames";
 import pure from "recompose/pure";
 
-import Popover from "./Popover.jsx";
+import Popover from "./Popover";
 
 // if the tooltip is passed a long description we'll want to conditionally
 // format it to make it easier to read.
diff --git a/frontend/src/metabase/components/Triggerable.jsx b/frontend/src/metabase/components/Triggerable.jsx
index 41843dcc453cc1c5b871a7e3850f90eaefa09d95..2103bbb588a6f1f563b41e71775b95639e1d37ec 100644
--- a/frontend/src/metabase/components/Triggerable.jsx
+++ b/frontend/src/metabase/components/Triggerable.jsx
@@ -3,7 +3,7 @@ import ReactDOM from "react-dom";
 
 import { isObscured } from "metabase/lib/dom";
 
-import Tooltip from "./Tooltip.jsx";
+import Tooltip from "./Tooltip";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/components/UserAvatar.jsx b/frontend/src/metabase/components/UserAvatar.jsx
index 90641f39ddfaea067f15d0724bca1ef26d78dbb6..f0ac0ecaa3c96901060c7ca0f9e40cfac27114b4 100644
--- a/frontend/src/metabase/components/UserAvatar.jsx
+++ b/frontend/src/metabase/components/UserAvatar.jsx
@@ -4,7 +4,7 @@ import styled from "styled-components";
 import { Flex } from "grid-styled";
 import { height } from "styled-system";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const Avatar = styled(Flex).attrs({
   align: "center",
@@ -20,7 +20,7 @@ const Avatar = styled(Flex).attrs({
 `;
 
 Avatar.defaultProps = {
-  bg: colors["brand"],
+  bg: color("brand"),
   color: "white",
   size: ["3em"],
 };
diff --git a/frontend/src/metabase/components/icons/FullscreenIcon.jsx b/frontend/src/metabase/components/icons/FullscreenIcon.jsx
index 38e8eb9005ce11229c1774b2df5f8437a2844a4b..6a5c28d8b2e46f12953a560770d9adfb49427c56 100644
--- a/frontend/src/metabase/components/icons/FullscreenIcon.jsx
+++ b/frontend/src/metabase/components/icons/FullscreenIcon.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const FullscreenIcon = ({ isFullscreen, ...props }) => (
   <Icon name={isFullscreen ? "contract" : "expand"} {...props} />
diff --git a/frontend/src/metabase/components/icons/NightModeIcon.jsx b/frontend/src/metabase/components/icons/NightModeIcon.jsx
index b1ffbbb840d25de4ae5e1affefbffe644fff2ed8..b75a0381bffb59d3fb086049b37f54f3546f0360 100644
--- a/frontend/src/metabase/components/icons/NightModeIcon.jsx
+++ b/frontend/src/metabase/components/icons/NightModeIcon.jsx
@@ -2,7 +2,7 @@
 
 import React from "react";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 type Props = {
   // ...IconProps,
diff --git a/frontend/src/metabase/containers/AddToDashSelectDashModal.jsx b/frontend/src/metabase/containers/AddToDashSelectDashModal.jsx
index d0d38e07bcf75a26490b34a24169f00c37d55be5..b343455b445360c8f0ed9f2f2f5157e277115702 100644
--- a/frontend/src/metabase/containers/AddToDashSelectDashModal.jsx
+++ b/frontend/src/metabase/containers/AddToDashSelectDashModal.jsx
@@ -6,7 +6,7 @@ import { Flex } from "grid-styled";
 
 import Icon from "metabase/components/Icon";
 import Link from "metabase/components/Link";
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalContent from "metabase/components/ModalContent";
 import DashboardPicker from "metabase/containers/DashboardPicker";
 
 import * as Urls from "metabase/lib/urls";
diff --git a/frontend/src/metabase/containers/ItemPicker.jsx b/frontend/src/metabase/containers/ItemPicker.jsx
index 199715105f0041d464c95d1836f0f8ff247a6d1c..b394d791ed2f79e0044d29bd401e9dcc1057e2dc 100644
--- a/frontend/src/metabase/containers/ItemPicker.jsx
+++ b/frontend/src/metabase/containers/ItemPicker.jsx
@@ -7,7 +7,7 @@ import Icon from "metabase/components/Icon";
 import Breadcrumbs from "metabase/components/Breadcrumbs";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import { connect } from "react-redux";
 
@@ -18,7 +18,7 @@ import EntityListLoader, {
 
 import Collections from "metabase/entities/collections";
 
-const COLLECTION_ICON_COLOR = colors["text-light"];
+const COLLECTION_ICON_COLOR = color("text-light");
 
 const isRoot = collection => collection.id === "root" || collection.id == null;
 
diff --git a/frontend/src/metabase/containers/Overworld.jsx b/frontend/src/metabase/containers/Overworld.jsx
index a0bed11f3dca1ffe1492a6fc442144249a51d54e..a4faa099787886bfd4e42ce757e0f0492359bb1d 100644
--- a/frontend/src/metabase/containers/Overworld.jsx
+++ b/frontend/src/metabase/containers/Overworld.jsx
@@ -8,7 +8,7 @@ import { createSelector } from "reselect";
 import CollectionItemsLoader from "metabase/containers/CollectionItemsLoader";
 import CandidateListLoader from "metabase/containers/CandidateListLoader";
 import ExplorePane from "metabase/components/ExplorePane";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import Tooltip from "metabase/components/Tooltip";
 import MetabotLogo from "metabase/components/MetabotLogo";
 import CollectionList from "metabase/components/CollectionList";
 
@@ -20,7 +20,7 @@ import Subhead from "metabase/components/Subhead";
 import RetinaImage from "react-retina-image";
 
 import * as Urls from "metabase/lib/urls";
-import colors, { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import Greeting from "metabase/lib/greeting";
 
 import Database from "metabase/entities/databases";
@@ -138,12 +138,12 @@ class Overworld extends React.Component {
                             pin.model
                           }`}
                           to={Urls.dashboard(pin.id)}
-                          hover={{ color: normal.blue }}
+                          hover={{ color: color("brand") }}
                         >
                           <Card hoverable p={3}>
                             <Icon
                               name="dashboard"
-                              color={normal.blue}
+                              color={color("brand")}
                               mb={2}
                               size={28}
                             />
@@ -163,7 +163,7 @@ class Overworld extends React.Component {
 
         <Box px={PAGE_PADDING} my={3}>
           <SectionHeading>{ROOT_COLLECTION.name}</SectionHeading>
-          <Box p={[1, 2]} mt={2} bg={colors["bg-medium"]}>
+          <Box p={[1, 2]} mt={2} bg={color("bg-medium")}>
             {this.props.collections.filter(
               c => c.id !== user.personal_collection_id,
             ).length > 0 ? (
@@ -193,11 +193,11 @@ class Overworld extends React.Component {
             )}
             <Link
               to="/collection/root"
-              color={normal.grey2}
+              color={color("text-medium")}
               className="text-brand-hover"
               data-metabase-event={`Homepage;Browse Items Clicked;`}
             >
-              <Flex color={colors["brand"]} p={2} my={1} align="center">
+              <Flex color={color("brand")} p={2} my={1} align="center">
                 <Box ml="auto" mr="auto">
                   <Flex align="center">
                     <h4>{t`Browse all items`}</h4>
@@ -223,19 +223,19 @@ class Overworld extends React.Component {
                       <GridItem w={[1, 1 / 3]} key={database.id}>
                         <Link
                           to={`browse/${database.id}`}
-                          hover={{ color: normal.blue }}
+                          hover={{ color: color("brand") }}
                           data-metabase-event={`Homepage;Browse DB Clicked; DB Type ${
                             database.engine
                           }`}
                         >
                           <Box
                             p={3}
-                            bg={colors["bg-medium"]}
+                            bg={color("bg-medium")}
                             className="hover-parent hover--visibility"
                           >
                             <Icon
                               name="database"
-                              color={normal.purple}
+                              color={color("database")}
                               mb={3}
                               size={28}
                             />
@@ -251,7 +251,7 @@ class Overworld extends React.Component {
                                     >
                                       <Icon
                                         name="reference"
-                                        color={normal.grey1}
+                                        color={color("text-light")}
                                       />
                                     </Link>
                                   </Tooltip>
@@ -301,13 +301,13 @@ export class AdminPinMessage extends React.Component {
         <SectionHeading>{t`Start here`}</SectionHeading>
 
         <Flex
-          bg={colors["bg-medium"]}
+          bg={color("bg-medium")}
           p={2}
           align="center"
           style={{ borderRadius: 6 }}
           className="hover-parent hover--visibility"
         >
-          <Icon name="dashboard" color={colors["brand"]} size={32} mr={1} />
+          <Icon name="dashboard" color={color("brand")} size={32} mr={1} />
           <Box ml={1}>
             <h3>{t`Your team's most important dashboards go here`}</h3>
             <p className="m0 mt1 text-medium text-bold">{jt`Pin dashboards in ${link} to have them appear in this space for everyone`}</p>
@@ -328,7 +328,7 @@ const SectionHeading = ({ children }) => (
   <Box mb={1}>
     <h5
       className="text-uppercase"
-      style={{ color: colors["text-medium"], fontWeight: 900 }}
+      style={{ color: color("text-medium"), fontWeight: 900 }}
     >
       {children}
     </h5>
diff --git a/frontend/src/metabase/containers/SaveQuestionModal.jsx b/frontend/src/metabase/containers/SaveQuestionModal.jsx
index 274b8f1cdaf28d8f326de555f843c2812572c524..b16d17bc115a9f2fcc93348a9c50d26bd433d9a6 100644
--- a/frontend/src/metabase/containers/SaveQuestionModal.jsx
+++ b/frontend/src/metabase/containers/SaveQuestionModal.jsx
@@ -3,9 +3,9 @@ import PropTypes from "prop-types";
 
 import { CSSTransitionGroup } from "react-transition-group";
 
-import FormField from "metabase/components/form/FormField.jsx";
-import ModalContent from "metabase/components/ModalContent.jsx";
-import Radio from "metabase/components/Radio.jsx";
+import FormField from "metabase/components/form/FormField";
+import ModalContent from "metabase/components/ModalContent";
+import Radio from "metabase/components/Radio";
 import Button from "metabase/components/Button";
 import CollectionSelect from "metabase/containers/CollectionSelect";
 
diff --git a/frontend/src/metabase/containers/UndoListing.jsx b/frontend/src/metabase/containers/UndoListing.jsx
index 3f5f4c1e81aa613fe4b2c15ba3e968b876f93346..4a296a2f4cccc33e39b439f9d13ddd7b50fa5759 100644
--- a/frontend/src/metabase/containers/UndoListing.jsx
+++ b/frontend/src/metabase/containers/UndoListing.jsx
@@ -8,7 +8,7 @@ import { Flex } from "grid-styled";
 import { t } from "ttag";
 import { capitalize, inflect } from "metabase/lib/formatting";
 
-import { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import { dismissUndo, performUndo } from "metabase/redux/undo";
 import { getUndos } from "metabase/selectors/undo";
 
@@ -84,8 +84,8 @@ export default class UndoListing extends Component {
               )}
               <Icon
                 ml={1}
-                color={normal.grey1}
-                hover={{ color: normal.grey2 }}
+                color={color("text-light")}
+                hover={{ color: color("text-medium") }}
                 name="close"
                 onClick={() => dismissUndo(undo.id)}
               />
diff --git a/frontend/src/metabase/containers/UserCollectionList.jsx b/frontend/src/metabase/containers/UserCollectionList.jsx
index 2048378af9bd767cd14229b4ef782e9484e14196..c4baf25589aad9ee4f42c59484893d9ffc71f5b0 100644
--- a/frontend/src/metabase/containers/UserCollectionList.jsx
+++ b/frontend/src/metabase/containers/UserCollectionList.jsx
@@ -2,7 +2,7 @@ import React from "react";
 import { Box, Flex } from "grid-styled";
 
 import * as Urls from "metabase/lib/urls";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import Card from "metabase/components/Card";
 import Icon from "metabase/components/Icon";
@@ -45,7 +45,7 @@ const UserCollectionList = () => (
                             <Icon
                               name="person"
                               mr={1}
-                              color={colors["text-medium"]}
+                              color={color("text-medium")}
                               size={18}
                             />
                             <h3>{user.common_name}</h3>
diff --git a/frontend/src/metabase/dashboard/components/AddSeriesModal.jsx b/frontend/src/metabase/dashboard/components/AddSeriesModal.jsx
index f836280d757051d43f96203bc135e26bc5e63f38..06477a1ca35b9f255145390872979c46eaa14491 100644
--- a/frontend/src/metabase/dashboard/components/AddSeriesModal.jsx
+++ b/frontend/src/metabase/dashboard/components/AddSeriesModal.jsx
@@ -2,14 +2,14 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 
-import Visualization from "metabase/visualizations/components/Visualization.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
-import CheckBox from "metabase/components/CheckBox.jsx";
+import Visualization from "metabase/visualizations/components/Visualization";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import Icon from "metabase/components/Icon";
+import Tooltip from "metabase/components/Tooltip";
+import CheckBox from "metabase/components/CheckBox";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import * as Q_DEPRECATED from "metabase/lib/query";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import { getVisualizationRaw } from "metabase/visualizations";
 
@@ -263,7 +263,7 @@ export default class AddSeriesModal extends Component {
             {this.state.state && (
               <div
                 className="spred flex layout-centered"
-                style={{ backgroundColor: colors["bg-white"] }}
+                style={{ backgroundColor: color("bg-white") }}
               >
                 {this.state.state === "loading" ? (
                   <div className="h3 rounded bordered p3 bg-white shadowed">
@@ -294,13 +294,13 @@ export default class AddSeriesModal extends Component {
           className="border-left flex flex-column"
           style={{
             width: 370,
-            backgroundColor: colors["bg-light"],
-            borderColor: colors["border"],
+            backgroundColor: color("bg-light"),
+            borderColor: color("border"),
           }}
         >
           <div
             className="flex-no-shrink border-bottom flex flex-row align-center"
-            style={{ borderColor: colors["border"] }}
+            style={{ borderColor: color("border") }}
           >
             <Icon className="ml2" name="search" size={16} />
             <input
diff --git a/frontend/src/metabase/dashboard/components/AddToDashSelectQuestionModal.jsx b/frontend/src/metabase/dashboard/components/AddToDashSelectQuestionModal.jsx
index 818a4c8371e4eee9bbd40aa6d0a877b6ffce9151..3e378558c1def4bf18e92ae913f201916f2718c6 100644
--- a/frontend/src/metabase/dashboard/components/AddToDashSelectQuestionModal.jsx
+++ b/frontend/src/metabase/dashboard/components/AddToDashSelectQuestionModal.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
-import AddToDashboard from "metabase/questions/containers/AddToDashboard.jsx";
+import AddToDashboard from "metabase/questions/containers/AddToDashboard";
 
 export default class AddToDashSelectQuestionModal extends Component {
   constructor(props, context) {
diff --git a/frontend/src/metabase/dashboard/components/DashCard.jsx b/frontend/src/metabase/dashboard/components/DashCard.jsx
index aab57cdc8c604eb55a941e8486cb6c9e24d84e26..33bbe4cdd8b659478965f3c7c09fa1ebc7f7b257 100644
--- a/frontend/src/metabase/dashboard/components/DashCard.jsx
+++ b/frontend/src/metabase/dashboard/components/DashCard.jsx
@@ -6,15 +6,15 @@ import visualizations, { getVisualizationRaw } from "metabase/visualizations";
 import Visualization, {
   ERROR_MESSAGE_GENERIC,
   ERROR_MESSAGE_PERMISSION,
-} from "metabase/visualizations/components/Visualization.jsx";
+} from "metabase/visualizations/components/Visualization";
 import QueryDownloadWidget from "metabase/query_builder/components/QueryDownloadWidget";
 
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
-import { ChartSettingsWithState } from "metabase/visualizations/components/ChartSettings.jsx";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
+import { ChartSettingsWithState } from "metabase/visualizations/components/ChartSettings";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
-import DashCardParameterMapper from "./DashCardParameterMapper.jsx";
+import DashCardParameterMapper from "./DashCardParameterMapper";
 
 import { IS_EMBED_PREVIEW } from "metabase/lib/embed";
 
diff --git a/frontend/src/metabase/dashboard/components/DashCardParameterMapper.jsx b/frontend/src/metabase/dashboard/components/DashCardParameterMapper.jsx
index e85ab03e28418d1a70dd6396f8e894c7cb966c9c..87c8e53e012a3d0a9df9b9536d78eb1a65d95927 100644
--- a/frontend/src/metabase/dashboard/components/DashCardParameterMapper.jsx
+++ b/frontend/src/metabase/dashboard/components/DashCardParameterMapper.jsx
@@ -1,9 +1,9 @@
 import React from "react";
 import { t } from "ttag";
 
-import DashCardCardParameterMapper from "../containers/DashCardCardParameterMapper.jsx";
+import DashCardCardParameterMapper from "../containers/DashCardCardParameterMapper";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const DashCardParameterMapper = ({ dashcard }) => (
   <div className="relative flex-full flex flex-column layout-centered">
@@ -11,8 +11,8 @@ const DashCardParameterMapper = ({ dashcard }) => (
       <div
         className="mx4 my1 p1 rounded"
         style={{
-          backgroundColor: colors["bg-light"],
-          color: colors["text-medium"],
+          backgroundColor: color("bg-light"),
+          color: color("text-medium"),
           marginTop: -10,
         }}
       >
diff --git a/frontend/src/metabase/dashboard/components/Dashboard.jsx b/frontend/src/metabase/dashboard/components/Dashboard.jsx
index d120e64aba7b7f2dc64b717e774cc6bd5ed0cdce..98a8010bc4f92902c9d602f18bdf8a4d069eb89d 100644
--- a/frontend/src/metabase/dashboard/components/Dashboard.jsx
+++ b/frontend/src/metabase/dashboard/components/Dashboard.jsx
@@ -6,11 +6,11 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Box } from "grid-styled";
 
-import DashboardHeader from "../components/DashboardHeader.jsx";
-import DashboardGrid from "../components/DashboardGrid.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import DashboardHeader from "../components/DashboardHeader";
+import DashboardGrid from "../components/DashboardGrid";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 import { t } from "ttag";
-import Parameters from "metabase/parameters/components/Parameters.jsx";
+import Parameters from "metabase/parameters/components/Parameters";
 import EmptyState from "metabase/components/EmptyState";
 
 import DashboardControls from "../hoc/DashboardControls";
diff --git a/frontend/src/metabase/dashboard/components/DashboardGrid.jsx b/frontend/src/metabase/dashboard/components/DashboardGrid.jsx
index 3acd7ba1700619744065b11b96139ed2188640a6..355a6df214991550f903e1ddaf7b5d5a799eb134 100644
--- a/frontend/src/metabase/dashboard/components/DashboardGrid.jsx
+++ b/frontend/src/metabase/dashboard/components/DashboardGrid.jsx
@@ -1,13 +1,13 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import GridLayout from "./grid/GridLayout.jsx";
-import DashCard from "./DashCard.jsx";
+import GridLayout from "./grid/GridLayout";
+import DashCard from "./DashCard";
 
-import Modal from "metabase/components/Modal.jsx";
-import ExplicitSize from "metabase/components/ExplicitSize.jsx";
-import RemoveFromDashboardModal from "./RemoveFromDashboardModal.jsx";
-import AddSeriesModal from "./AddSeriesModal.jsx";
+import Modal from "metabase/components/Modal";
+import ExplicitSize from "metabase/components/ExplicitSize";
+import RemoveFromDashboardModal from "./RemoveFromDashboardModal";
+import AddSeriesModal from "./AddSeriesModal";
 
 import { getVisualizationRaw } from "metabase/visualizations";
 import MetabaseAnalytics from "metabase/lib/analytics";
diff --git a/frontend/src/metabase/dashboard/components/DashboardMoveModal.jsx b/frontend/src/metabase/dashboard/components/DashboardMoveModal.jsx
index 848652083b405e4c439e0c515de1273bda704345..fa39b757bca8f6504740ecb38e7a6a10b459e48c 100644
--- a/frontend/src/metabase/dashboard/components/DashboardMoveModal.jsx
+++ b/frontend/src/metabase/dashboard/components/DashboardMoveModal.jsx
@@ -9,7 +9,7 @@ import Link from "metabase/components/Link";
 import CollectionMoveModal from "metabase/containers/CollectionMoveModal";
 
 import * as Urls from "metabase/lib/urls";
-import { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import Dashboards from "metabase/entities/dashboards";
 import { ROOT_COLLECTION } from "metabase/entities/collections";
@@ -55,7 +55,7 @@ const DashbordMoveToast = ({ collection }) => (
     {jt`Dashboard moved to ${(
       <Link
         ml={1}
-        color={normal.blue}
+        color={color("brand")}
         to={Urls.collection(collection && collection.id)}
       >
         {collection ? collection.name : ROOT_COLLECTION.name}
diff --git a/frontend/src/metabase/dashboard/components/RefreshWidget.jsx b/frontend/src/metabase/dashboard/components/RefreshWidget.jsx
index 3c131e4afc64d2daeb582f44c9c01f3bf79480cf..e48b6f71d5100233892b6bb285fb69093705059d 100644
--- a/frontend/src/metabase/dashboard/components/RefreshWidget.jsx
+++ b/frontend/src/metabase/dashboard/components/RefreshWidget.jsx
@@ -1,11 +1,11 @@
 import React, { Component } from "react";
 import styles from "./RefreshWidget.css";
 
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import ClockIcon from "metabase/components/icons/ClockIcon.jsx";
-import CountdownIcon from "metabase/components/icons/CountdownIcon.jsx";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import Tooltip from "metabase/components/Tooltip";
+import Icon from "metabase/components/Icon";
+import ClockIcon from "metabase/components/icons/ClockIcon";
+import CountdownIcon from "metabase/components/icons/CountdownIcon";
 import { t } from "ttag";
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/dashboard/components/grid/GridLayout.jsx b/frontend/src/metabase/dashboard/components/grid/GridLayout.jsx
index a7208e8e242ea1640c2d333bcd79a0501c6128fe..9db4e1ae42c628f58ed262fb1e5d3dbcd457fa83 100644
--- a/frontend/src/metabase/dashboard/components/grid/GridLayout.jsx
+++ b/frontend/src/metabase/dashboard/components/grid/GridLayout.jsx
@@ -1,10 +1,10 @@
 import React, { Component } from "react";
 import ReactDOM from "react-dom";
 
-import GridItem from "./GridItem.jsx";
+import GridItem from "./GridItem";
 
 import _ from "underscore";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export default class GridLayout extends Component {
   constructor(props, context) {
@@ -238,9 +238,9 @@ export default class GridLayout extends Component {
       _(cols)
         .times(
           i =>
-            `<rect stroke='${
-              colors["border"]
-            }' stroke-width='1' fill='none' x='${Math.round(
+            `<rect stroke='${color(
+              "border",
+            )}' stroke-width='1' fill='none' x='${Math.round(
               margin / 2 + i * cellSize.width,
             ) + 1.5}' y='${margin / 2 + 1.5}' width='${Math.round(
               cellSize.width - margin - 3,
diff --git a/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx b/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx
index 5eb13f59c077180ec691155d8202a6fb0d4b39f5..9913e39ce9d3483b78cdf7f42caa8430ef95da0f 100644
--- a/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx
+++ b/frontend/src/metabase/dashboard/containers/AutomaticDashboardApp.jsx
@@ -28,7 +28,7 @@ import * as Urls from "metabase/lib/urls";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import * as Q from "metabase/lib/query/query";
 import Dimension from "metabase-lib/lib/Dimension";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import { dissoc } from "icepick";
 
@@ -247,7 +247,7 @@ const SuggestionsList = ({ suggestions, section }) => (
         {suggestions[s].length > 0 &&
           suggestions[s].map((item, itemIndex) => (
             <Link
-              hover={{ color: colors["brand"] }}
+              hover={{ color: color("brand") }}
               key={itemIndex}
               to={item.url}
               className="block hover-parent hover--visibility"
@@ -258,14 +258,14 @@ const SuggestionsList = ({ suggestions, section }) => (
                 <Flex align="center">
                   <Icon
                     name={RELATED_CONTENT[s].icon}
-                    color={colors["accent4"]}
+                    color={color("accent4")}
                     mr={1}
                     size={22}
                   />
                   <h4 className="text-wrap">{item.title}</h4>
                   <Box ml="auto" className="hover-child">
                     <Tooltip tooltip={item.description}>
-                      <Icon name="question" color={colors["bg-dark"]} />
+                      <Icon name="question" color={color("bg-dark")} />
                     </Tooltip>
                   </Box>
                 </Flex>
@@ -282,7 +282,7 @@ const SuggetsionSectionHeading = ({ children }) => (
     style={{
       fontWeight: 900,
       textTransform: "uppercase",
-      color: colors["text-medium"],
+      color: color("text-medium"),
     }}
     className="mb1"
   >
diff --git a/frontend/src/metabase/dashboard/containers/DashCardCardParameterMapper.jsx b/frontend/src/metabase/dashboard/containers/DashCardCardParameterMapper.jsx
index a3024a655b7c6c913082be2aeb136c763f1ba571..0eaaf28880d16ad1ababf2849753ee078ccc4c6f 100644
--- a/frontend/src/metabase/dashboard/containers/DashCardCardParameterMapper.jsx
+++ b/frontend/src/metabase/dashboard/containers/DashCardCardParameterMapper.jsx
@@ -6,10 +6,10 @@ import { connect } from "react-redux";
 import { t } from "ttag";
 import S from "./DashCardCardParameterMapper.css";
 
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import AccordionList from "metabase/components/AccordionList.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import Icon from "metabase/components/Icon";
+import AccordionList from "metabase/components/AccordionList";
+import Tooltip from "metabase/components/Tooltip";
 
 import { fetchDatabaseMetadata } from "metabase/redux/metadata";
 
diff --git a/frontend/src/metabase/dashboard/containers/DashboardApp.jsx b/frontend/src/metabase/dashboard/containers/DashboardApp.jsx
index a42b978a6a927c2e10dfead445049efd26c93634..452a52be5150ef491ce6e5aed9964797f8fc5c3b 100644
--- a/frontend/src/metabase/dashboard/containers/DashboardApp.jsx
+++ b/frontend/src/metabase/dashboard/containers/DashboardApp.jsx
@@ -5,7 +5,7 @@ import { connect } from "react-redux";
 import { push } from "react-router-redux";
 import title from "metabase/hoc/Title";
 
-import Dashboard from "metabase/dashboard/components/Dashboard.jsx";
+import Dashboard from "metabase/dashboard/components/Dashboard";
 
 import { fetchDatabaseMetadata } from "metabase/redux/metadata";
 import { setErrorPage } from "metabase/redux/app";
diff --git a/frontend/src/metabase/entities/collections.js b/frontend/src/metabase/entities/collections.js
index ff40e74de340cb21a2f7af3e527a7e0e3ccb37d4..b2d8cd3457c8e8815ee8ae7a9627a8c692212820 100644
--- a/frontend/src/metabase/entities/collections.js
+++ b/frontend/src/metabase/entities/collections.js
@@ -2,7 +2,7 @@
 
 import { createEntity, undo } from "metabase/lib/entities";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import * as Urls from "metabase/lib/urls";
 
 import { CollectionSchema } from "metabase/schema";
@@ -86,7 +86,7 @@ const Collections = createEntity({
   form: {
     fields: (
       values = {
-        color: colors.brand,
+        color: color("brand"),
       },
     ) => [
       {
@@ -108,7 +108,7 @@ const Collections = createEntity({
         name: "color",
         title: t`Color`,
         type: "hidden",
-        initial: () => colors.brand,
+        initial: () => color("brand"),
         validate: color => !color && t`Color is required`,
       },
       {
diff --git a/frontend/src/metabase/entities/dashboards.js b/frontend/src/metabase/entities/dashboards.js
index ad8d214ce350fc783ec2d1468ba0e320c14496f9..0abb9e08c1c503b1b277a91d854a0a087fa8a7aa 100644
--- a/frontend/src/metabase/entities/dashboards.js
+++ b/frontend/src/metabase/entities/dashboards.js
@@ -9,7 +9,7 @@ import {
 
 import { createEntity, undo } from "metabase/lib/entities";
 import * as Urls from "metabase/lib/urls";
-import { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import { assocIn } from "icepick";
 import { t } from "ttag";
 
@@ -132,7 +132,7 @@ const Dashboards = createEntity({
     getName: dashboard => dashboard && dashboard.name,
     getUrl: dashboard => dashboard && Urls.dashboard(dashboard.id),
     getIcon: dashboard => "dashboard",
-    getColor: () => normal.blue,
+    getColor: () => color("dashboard"),
   },
 
   form: {
diff --git a/frontend/src/metabase/entities/metrics.js b/frontend/src/metabase/entities/metrics.js
index 3a35fcb56620f99f9b7c4312c3a5b6af3b9196ec..0dfd89c2cb138e86213048a737ec814f3a608bb3 100644
--- a/frontend/src/metabase/entities/metrics.js
+++ b/frontend/src/metabase/entities/metrics.js
@@ -1,7 +1,7 @@
 import { createEntity } from "metabase/lib/entities";
 
 import { MetricSchema } from "metabase/schema";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import * as Urls from "metabase/lib/urls";
 
 const Metrics = createEntity({
@@ -26,7 +26,7 @@ const Metrics = createEntity({
     getName: metric => metric && metric.name,
     getUrl: metric =>
       Urls.tableRowsQuery(metric.database_id, metric.table_id, metric.id),
-    getColor: metric => colors["accent1"],
+    getColor: metric => color("accent1"),
     getIcon: metric => "sum",
   },
 
diff --git a/frontend/src/metabase/entities/pulses.js b/frontend/src/metabase/entities/pulses.js
index 0aebd4d7bb6c1be2d43d35d53c57e07e20921972..8845f407a6ef5eeb9da53972d43b7927351e92b2 100644
--- a/frontend/src/metabase/entities/pulses.js
+++ b/frontend/src/metabase/entities/pulses.js
@@ -1,6 +1,6 @@
 import { createEntity, undo } from "metabase/lib/entities";
 import * as Urls from "metabase/lib/urls";
-import { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import {
   canonicalCollectionId,
@@ -41,7 +41,7 @@ const Pulses = createEntity({
     getName: pulse => pulse && pulse.name,
     getUrl: pulse => pulse && Urls.pulse(pulse.id),
     getIcon: pulse => "pulse",
-    getColor: pulse => normal.yellow,
+    getColor: pulse => color("pulse"),
   },
 
   form: {
diff --git a/frontend/src/metabase/entities/questions.js b/frontend/src/metabase/entities/questions.js
index 962ed1a249831447a162bc68c0659df8adf58788..351d979a30fe053296feb4158774c6ed90bff899 100644
--- a/frontend/src/metabase/entities/questions.js
+++ b/frontend/src/metabase/entities/questions.js
@@ -4,7 +4,7 @@ import { assocIn } from "icepick";
 
 import { createEntity, undo } from "metabase/lib/entities";
 import * as Urls from "metabase/lib/urls";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import {
   canonicalCollectionId,
@@ -64,7 +64,7 @@ const Questions = createEntity({
   objectSelectors: {
     getName: question => question && question.name,
     getUrl: question => question && Urls.question(question.id),
-    getColor: () => colors["text-medium"],
+    getColor: () => color("text-medium"),
     getIcon: question =>
       (require("metabase/visualizations").default.get(question.display) || {})
         .iconName || "beaker",
diff --git a/frontend/src/metabase/entities/segments.js b/frontend/src/metabase/entities/segments.js
index b5ea283c9c54fb355f745ac73dfc0edb1e5e79fc..21fb5615ec0051119458243cceaafcbfe9645892 100644
--- a/frontend/src/metabase/entities/segments.js
+++ b/frontend/src/metabase/entities/segments.js
@@ -3,7 +3,7 @@
 import { createEntity } from "metabase/lib/entities";
 
 import { SegmentSchema } from "metabase/schema";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import * as Urls from "metabase/lib/urls";
 
 const Segments = createEntity({
@@ -33,7 +33,7 @@ const Segments = createEntity({
         null,
         segment.id,
       ),
-    getColor: segment => colors["accent7"],
+    getColor: segment => color("accent7"),
     getIcon: segment => "segment",
   },
 
diff --git a/frontend/src/metabase/entities/tables.js b/frontend/src/metabase/entities/tables.js
index 1f19a26cf81254e08bcca129c985f3d926be6642..6417822dc1333a4bea9f2382416d368696ca16ce 100644
--- a/frontend/src/metabase/entities/tables.js
+++ b/frontend/src/metabase/entities/tables.js
@@ -9,7 +9,7 @@ import {
 import _ from "underscore";
 
 import * as Urls from "metabase/lib/urls";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import { createSelector } from "reselect";
 
@@ -172,7 +172,7 @@ const Tables = createEntity({
     getUrl: table =>
       Urls.tableRowsQuery(table.database_id, table.table_id, null),
     getIcon: table => "table",
-    getColor: table => colors["accent2"],
+    getColor: table => color("accent2"),
   },
 
   selectors: {
diff --git a/frontend/src/metabase/home/components/Activity.jsx b/frontend/src/metabase/home/components/Activity.jsx
index 4aee6c711eec748cf44379d6cd0c6f20722b5b33..50caa2feec8ed1c784d628dbaf11dac9e7891f12 100644
--- a/frontend/src/metabase/home/components/Activity.jsx
+++ b/frontend/src/metabase/home/components/Activity.jsx
@@ -4,11 +4,11 @@ import { Link } from "react-router";
 import _ from "underscore";
 import { t } from "ttag";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
-import ActivityItem from "./ActivityItem.jsx";
-import ActivityStory from "./ActivityStory.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import ActivityItem from "./ActivityItem";
+import ActivityStory from "./ActivityStory";
 
 import * as Urls from "metabase/lib/urls";
 
@@ -18,12 +18,12 @@ export default class Activity extends Component {
     this.state = { error: null, userColors: {} };
 
     this.colorClasses = [
-      colors["brand"],
-      colors["accent1"],
-      colors["accent2"],
-      colors["accent3"],
-      colors["accent4"],
-      colors["accent5"],
+      color("brand"),
+      color("accent1"),
+      color("accent2"),
+      color("accent3"),
+      color("accent4"),
+      color("accent5"),
     ];
   }
 
diff --git a/frontend/src/metabase/home/components/ActivityItem.jsx b/frontend/src/metabase/home/components/ActivityItem.jsx
index 3b00919ca02e0a7905001b78844f0c8ed51ea409..bfee02ee4f919de72de0bd823c7713b1b0f02712 100644
--- a/frontend/src/metabase/home/components/ActivityItem.jsx
+++ b/frontend/src/metabase/home/components/ActivityItem.jsx
@@ -1,9 +1,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
-import Icon from "metabase/components/Icon.jsx";
-import IconBorder from "metabase/components/IconBorder.jsx";
-import UserAvatar from "metabase/components/UserAvatar.jsx";
-import colors from "metabase/lib/colors";
+import Icon from "metabase/components/Icon";
+import IconBorder from "metabase/components/IconBorder";
+import UserAvatar from "metabase/components/UserAvatar";
+import { color } from "metabase/lib/colors";
 
 export default class ActivityItem extends Component {
   static propTypes = {
@@ -21,7 +21,7 @@ export default class ActivityItem extends Component {
           {item.user ? (
             <UserAvatar user={item.user} bg={userColors} />
           ) : (
-            <IconBorder style={{ color: colors["text-light"] }}>
+            <IconBorder style={{ color: color("text-light") }}>
               <Icon name="sync" size={16} />
             </IconBorder>
           )}
diff --git a/frontend/src/metabase/home/components/ActivityStory.jsx b/frontend/src/metabase/home/components/ActivityStory.jsx
index a95cfa56c54ef5b4088fc2edfa1987fe4858509c..c4bd0824d72f1b0c4d720258d703f91bbb6c5655 100644
--- a/frontend/src/metabase/home/components/ActivityStory.jsx
+++ b/frontend/src/metabase/home/components/ActivityStory.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Link } from "react-router";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export default class ActivityStory extends Component {
   constructor(props, context) {
@@ -9,7 +9,7 @@ export default class ActivityStory extends Component {
 
     this.styles = {
       borderWidth: "2px",
-      borderColor: colors["border"],
+      borderColor: color("border"),
     };
   }
 
@@ -30,7 +30,7 @@ export default class ActivityStory extends Component {
         style={{
           borderWidth: "3px",
           marginLeft: "22px",
-          borderColor: colors["border"],
+          borderColor: color("border"),
         }}
       >
         <div className="flex full ml4 bordered rounded p2" style={this.styles}>
diff --git a/frontend/src/metabase/home/components/NewUserOnboardingModal.jsx b/frontend/src/metabase/home/components/NewUserOnboardingModal.jsx
index d5d60a6b025ebce4663cdb5a1e454e474ccfa049..f92c84eae8aee6d7a90ac1d5589139a9dd1c51ef 100644
--- a/frontend/src/metabase/home/components/NewUserOnboardingModal.jsx
+++ b/frontend/src/metabase/home/components/NewUserOnboardingModal.jsx
@@ -4,7 +4,7 @@ import StepIndicators from "metabase/components/StepIndicators";
 import RetinaImage from "react-retina-image";
 import { t } from "ttag";
 import MetabaseSettings from "metabase/lib/settings";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 type Props = {
   onClose: () => void,
@@ -107,8 +107,8 @@ const OnboardingImages = ({ currentStep }, { currentStep: object }) => (
   <div
     style={{
       position: "relative",
-      backgroundColor: colors["bg-medium"],
-      borderBottom: `1px solid ${colors["border"]}`,
+      backgroundColor: color("bg-medium"),
+      borderBottom: `1px solid ${color("border")}`,
       height: 254,
       paddingTop: "3em",
       paddingBottom: "3em",
diff --git a/frontend/src/metabase/home/components/NextStep.jsx b/frontend/src/metabase/home/components/NextStep.jsx
index 4722b1a478c5d8b964161a079e0b8f964cf24fe8..9833661bcffab249c4ba4c27e008063a60a39bb4 100644
--- a/frontend/src/metabase/home/components/NextStep.jsx
+++ b/frontend/src/metabase/home/components/NextStep.jsx
@@ -4,7 +4,7 @@ import { t } from "ttag";
 
 import { SetupApi } from "metabase/services";
 
-import SidebarSection from "./SidebarSection.jsx";
+import SidebarSection from "./SidebarSection";
 
 export default class NextStep extends Component {
   constructor(props, context) {
diff --git a/frontend/src/metabase/home/components/RecentViews.jsx b/frontend/src/metabase/home/components/RecentViews.jsx
index c829102f02b51955be3bcf56889daa70d757eddc..0dbe3a120179695f512f62a76a2cd4286553430f 100644
--- a/frontend/src/metabase/home/components/RecentViews.jsx
+++ b/frontend/src/metabase/home/components/RecentViews.jsx
@@ -2,13 +2,13 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 import Ellipsified from "metabase/components/Ellipsified";
 import Link from "metabase/components/Link";
-import SidebarSection from "./SidebarSection.jsx";
+import SidebarSection from "./SidebarSection";
 import * as Urls from "metabase/lib/urls";
 
-import { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export default class RecentViews extends Component {
   static propTypes = {
@@ -49,7 +49,9 @@ export default class RecentViews extends Component {
                     size={18}
                     style={{
                       color:
-                        iconName === "dashboard" ? normal.purple : normal.blue,
+                        iconName === "dashboard"
+                          ? color("dashboard")
+                          : color("brand"),
                     }}
                   />
                   <Link
diff --git a/frontend/src/metabase/home/components/SidebarSection.jsx b/frontend/src/metabase/home/components/SidebarSection.jsx
index 64de827720c4dbe2eef75a261a3f13c8fd1ae185..76743b24e92f61245e731fd2cca768e4cfe6fede 100644
--- a/frontend/src/metabase/home/components/SidebarSection.jsx
+++ b/frontend/src/metabase/home/components/SidebarSection.jsx
@@ -1,7 +1,7 @@
 import React from "react";
 
-import Icon from "metabase/components/Icon.jsx";
-import colors from "metabase/lib/colors";
+import Icon from "metabase/components/Icon";
+import { color } from "metabase/lib/colors";
 
 const SidebarSection = ({ title, icon, extra, children }) => (
   <div className="px2 pt1">
@@ -12,7 +12,7 @@ const SidebarSection = ({ title, icon, extra, children }) => (
     </div>
     <div
       className="rounded bg-white"
-      style={{ border: `1px solid ${colors["border"]}` }}
+      style={{ border: `1px solid ${color("border")}` }}
     >
       {children}
     </div>
diff --git a/frontend/src/metabase/home/containers/SearchApp.jsx b/frontend/src/metabase/home/containers/SearchApp.jsx
index b12e483a76566c89312a386c11e6f56a82d00003..29ced20aa52e77828baab2ee9895991886ebcdd1 100644
--- a/frontend/src/metabase/home/containers/SearchApp.jsx
+++ b/frontend/src/metabase/home/containers/SearchApp.jsx
@@ -15,7 +15,7 @@ import EntityItem from "metabase/components/EntityItem";
 import Subhead from "metabase/components/Subhead";
 import { FILTERS } from "metabase/components/ItemTypeFilterBar";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import Icon from "metabase/components/Icon";
 
 const PAGE_PADDING = [1, 2, 4];
@@ -103,7 +103,7 @@ export default class SearchApp extends React.Component {
                     <Link
                       className="flex align-center"
                       mb={3}
-                      color={!location.query.type ? colors.brand : "inherit"}
+                      color={!location.query.type ? color("brand") : "inherit"}
                       to={{
                         pathname: location.pathname,
                         query: { ...location.query, type: null },
@@ -120,8 +120,8 @@ export default class SearchApp extends React.Component {
                       }
 
                       const color = isActive
-                        ? colors.brand
-                        : colors["text-medium"];
+                        ? color("brand")
+                        : color("text-medium");
 
                       return (
                         <Link
@@ -158,7 +158,7 @@ const SearchResultSection = ({ title, items }) => (
         case "segment":
         case "metric":
           extraInfo = (
-            <Flex align="center" color={colors["text-medium"]}>
+            <Flex align="center" color={color("text-medium")}>
               <Icon name="database" size={8} mr="4px" />
               <span className="text-small text-bold" style={{ lineHeight: 1 }}>
                 <Database.Name id={item.database_id} />
@@ -171,7 +171,7 @@ const SearchResultSection = ({ title, items }) => (
         default:
           extraInfo = (
             <div className="inline-block">
-              <Flex align="center" color={colors["text-medium"]}>
+              <Flex align="center" color={color("text-medium")}>
                 <Icon name="all" size={10} mr="4px" />
                 <span
                   className="text-small text-bold"
diff --git a/frontend/src/metabase/lib/api.js b/frontend/src/metabase/lib/api.js
index fe6334a2200cdfce488892444d01c67ae653da89..868171ded8ae2e5a52c27faffef7c82e7010aa25 100644
--- a/frontend/src/metabase/lib/api.js
+++ b/frontend/src/metabase/lib/api.js
@@ -1,6 +1,7 @@
 /* @flow weak */
 
 import querystring from "querystring";
+import JSONbig from "json-bigint";
 
 import EventEmitter from "events";
 
@@ -177,7 +178,7 @@ export class Api extends EventEmitter {
         if (xhr.readyState === XMLHttpRequest.DONE) {
           let body = xhr.responseText;
           try {
-            body = JSON.parse(body);
+            body = JSONbig.parse(body);
           } catch (e) {}
           if (xhr.status >= 200 && xhr.status <= 299) {
             if (options.transformResponse) {
diff --git a/frontend/src/metabase/lib/colors.js b/frontend/src/metabase/lib/colors.js
index 73c7aa6cd34e6f04bd5b9fda31a882db9027ff1a..03383744fd018a12c85c8eda241a65ff04817f97 100644
--- a/frontend/src/metabase/lib/colors.js
+++ b/frontend/src/metabase/lib/colors.js
@@ -52,6 +52,9 @@ export default colors;
 export const aliases = {
   summarize: "accent1",
   filter: "accent7",
+  database: "accent2",
+  dashboard: "brand",
+  pulse: "accent4",
 };
 
 export const harmony = [];
@@ -199,6 +202,7 @@ const PREFERRED_COLORS = {
     "success",
     "succeeded",
     "pass",
+    "passed",
     "valid",
     "complete",
     "completed",
@@ -207,6 +211,7 @@ const PREFERRED_COLORS = {
     "profit",
   ],
   [colors["error"]]: [
+    "error",
     "fail",
     "failed",
     "failure",
@@ -219,7 +224,7 @@ const PREFERRED_COLORS = {
     "deleted",
     "pending",
   ],
-  [colors["warning"]]: ["warn", "warning", "incomplete"],
+  [colors["warning"]]: ["warn", "warning", "incomplete", "unstable"],
   [colors["brand"]]: ["count"],
   [colors["accent1"]]: ["sum"],
   [colors["accent2"]]: ["average"],
diff --git a/frontend/src/metabase/lib/dataset.js b/frontend/src/metabase/lib/dataset.js
index bda6ece808a63fee1d826385a54c8fcc74a3e086..5138a6e5ad9c5e87e5db8ad18f015c2fd497e1df 100644
--- a/frontend/src/metabase/lib/dataset.js
+++ b/frontend/src/metabase/lib/dataset.js
@@ -80,9 +80,6 @@ export function fieldRefForColumnWithLegacyFallback(
 /**
  * Returns a MBQL field reference (FieldReference) for a given result dataset column
  *
- * NOTE: this returns non-normalized ["fk->", 1, 2] style fk field references
- * which is unfortunately used in table.columns visualization_settings
- *
  * @param  {Column} column Dataset result column
  * @param  {?Column[]} columns Full array of columns, unfortunately needed to determine the aggregation index
  * @return {?FieldReference} MBQL field reference
diff --git a/frontend/src/metabase/lib/formatting.js b/frontend/src/metabase/lib/formatting.js
index 9b30fa8b99a075d5d7cde93dd7c7651e0daf8aaf..b138509710b2f57e96315ab72796b4d26eac4012 100644
--- a/frontend/src/metabase/lib/formatting.js
+++ b/frontend/src/metabase/lib/formatting.js
@@ -9,8 +9,9 @@ import { ngettext, msgid } from "ttag";
 
 import Mustache from "mustache";
 import ReactMarkdown from "react-markdown";
+import BigNumber from "bignumber.js";
 
-import ExternalLink from "metabase/components/ExternalLink.jsx";
+import ExternalLink from "metabase/components/ExternalLink";
 
 import {
   isDate,
@@ -719,8 +720,13 @@ export function formatValueRaw(value: Value, options: FormattingOptions = {}) {
       return formatNumber(value, options);
     }
   } else if (typeof value === "object") {
-    // no extra whitespace for table cells
-    return JSON.stringify(value);
+    // Don't want to add extra quotes if BigNumber
+    if (value instanceof BigNumber) {
+      return value.toString();
+    } else {
+      // no extra whitespace for table cells
+      return JSON.stringify(value);
+    }
   } else {
     return String(value);
   }
diff --git a/frontend/src/metabase/lib/query_time.js b/frontend/src/metabase/lib/query_time.js
index bb4fad139b2c87b229280ea39986680dff132033..3b99ff589d20603844fbb9e05338d8ff3305b0e9 100644
--- a/frontend/src/metabase/lib/query_time.js
+++ b/frontend/src/metabase/lib/query_time.js
@@ -69,7 +69,7 @@ export function expandTimeIntervalFilter(filter) {
     n = 1;
   }
 
-  field = ["datetime-field", field, "as", unit];
+  field = ["datetime-field", field, unit];
 
   if (n < -1) {
     return [
diff --git a/frontend/src/metabase/meta/Dashboard.js b/frontend/src/metabase/meta/Dashboard.js
index 1466034f43af480ec381b9f63af689a760459353..8f353e1fb9a4a25a868d38cbf7765acdb510bd44 100644
--- a/frontend/src/metabase/meta/Dashboard.js
+++ b/frontend/src/metabase/meta/Dashboard.js
@@ -217,7 +217,7 @@ export function getTableDimensions(
   return _.chain(table.fields)
     .map(field => {
       const targetField = field.target;
-      if (targetField && depth > 0) {
+      if (targetField && depth > 0 && targetField.table) {
         const targetTable = targetField.table;
         return getTableDimensions(targetTable, depth - 1, filter).map(
           (dimension: Dimension) => ({
diff --git a/frontend/src/metabase/modes/components/actions/CountByTimeAction.jsx b/frontend/src/metabase/modes/components/actions/CountByTimeAction.jsx
index a71dfa7a59165cf3e85f9b3ff4dcb51a8c05a608..4473ff01a0c1dd893011b9c81d9eed3fd0e9949b 100644
--- a/frontend/src/metabase/modes/components/actions/CountByTimeAction.jsx
+++ b/frontend/src/metabase/modes/components/actions/CountByTimeAction.jsx
@@ -31,12 +31,7 @@ export default ({ question }: ClickActionProps): ClickAction[] => {
       question: () =>
         question
           .summarize(["count"])
-          .breakout([
-            "datetime-field",
-            ["field-id", dateField.id],
-            "as",
-            "day",
-          ]),
+          .breakout(["datetime-field", ["field-id", dateField.id], "day"]),
     },
   ];
 };
diff --git a/frontend/src/metabase/modes/lib/actions.js b/frontend/src/metabase/modes/lib/actions.js
index 2614dd6de83decc7a62883b71788823693b237a4..fd430ef34942d8c80881fd0cf1ceab586e27d102 100644
--- a/frontend/src/metabase/modes/lib/actions.js
+++ b/frontend/src/metabase/modes/lib/actions.js
@@ -127,7 +127,7 @@ export const drillFilter = (card, value, column) => {
   if (isDate(column)) {
     filter = [
       "=",
-      ["datetime-field", getFieldRefFromColumn(column), "as", column.unit],
+      ["datetime-field", getFieldRefFromColumn(column), column.unit],
       parseTimestamp(value, column.unit).format(),
     ];
   } else {
@@ -293,12 +293,7 @@ export const updateDateTimeFilter = (card, column, start, end): CardObject => {
     }
 
     // update the breakout
-    newCard = addOrUpdateBreakout(newCard, [
-      "datetime-field",
-      fieldRef,
-      "as",
-      unit,
-    ]);
+    newCard = addOrUpdateBreakout(newCard, ["datetime-field", fieldRef, unit]);
 
     // round to start of the original unit
     start = start.startOf(column.unit);
@@ -311,14 +306,14 @@ export const updateDateTimeFilter = (card, column, start, end): CardObject => {
       // is the start and end are the same (in whatever the original unit was) then just do an "="
       return addOrUpdateFilter(newCard, [
         "=",
-        ["datetime-field", fieldRef, "as", column.unit],
+        ["datetime-field", fieldRef, column.unit],
         start.format(),
       ]);
     } else {
       // otherwise do a between
       return addOrUpdateFilter(newCard, [
         "between",
-        ["datetime-field", fieldRef, "as", column.unit],
+        ["datetime-field", fieldRef, column.unit],
         start.format(),
         end.format(),
       ]);
diff --git a/frontend/src/metabase/nav/containers/Navbar.jsx b/frontend/src/metabase/nav/containers/Navbar.jsx
index 02d96ab8c9738f799f4c7a85dcf6759b91263383..b04a1d7179c88eff4c1feb7a36dbbf3c06c0a23f 100644
--- a/frontend/src/metabase/nav/containers/Navbar.jsx
+++ b/frontend/src/metabase/nav/containers/Navbar.jsx
@@ -10,10 +10,9 @@ import { t } from "ttag";
 import { Flex } from "grid-styled";
 import styled from "styled-components";
 import { space } from "styled-system";
-import color from "color";
 
 import * as Urls from "metabase/lib/urls";
-import colors, { darken } from "metabase/lib/colors";
+import { color, darken, lighten } from "metabase/lib/colors";
 
 import Icon, { IconWrapper } from "metabase/components/Icon";
 import Link from "metabase/components/Link";
@@ -61,15 +60,11 @@ const AdminNavItem = ({ name, path, currentPath }) => (
   </li>
 );
 
-const DefaultSearchColor = color(colors.brand)
-  .lighten(0.07)
-  .string();
-const ActiveSearchColor = color(colors.brand)
-  .lighten(0.1)
-  .string();
+const DefaultSearchColor = lighten("brand", 0.07);
+const ActiveSearchColor = lighten("brand", 0.1);
 
 const NavHover = {
-  backgroundColor: darken(colors["brand"]),
+  backgroundColor: darken(color("brand")),
   color: "white",
 };
 
@@ -98,7 +93,7 @@ const SearchInput = styled.input`
     outline: none;
   }
   &::placeholder {
-    color: ${colors["text-white"]};
+    color: ${color("text-white")};
   }
 `;
 
@@ -321,7 +316,7 @@ export default class Navbar extends Component {
               to={Urls.newQuestionFlow()}
               p={1}
               hover={{
-                backgroundColor: darken(colors["brand"]),
+                backgroundColor: darken(color("brand")),
               }}
               className="flex align-center rounded transition-background"
               data-metabase-event={`NavBar;New Question`}
@@ -338,7 +333,7 @@ export default class Navbar extends Component {
               className="flex align-center rounded transition-background"
               data-metabase-event={`NavBar;Data Browse`}
               hover={{
-                backgroundColor: darken(colors["brand"]),
+                backgroundColor: darken(color("brand")),
               }}
             >
               <Icon name="table_spaced" size={14} />
diff --git a/frontend/src/metabase/new_query/components/NewQueryOption.jsx b/frontend/src/metabase/new_query/components/NewQueryOption.jsx
index 3ee6d8d9946999947388b878455be91b1f40173f..34565b3be576d765d68ee4e6f9930c4072b601cc 100644
--- a/frontend/src/metabase/new_query/components/NewQueryOption.jsx
+++ b/frontend/src/metabase/new_query/components/NewQueryOption.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import cx from "classnames";
 import { Link } from "react-router";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export default class NewQueryOption extends Component {
   props: {
@@ -26,8 +26,8 @@ export default class NewQueryOption extends Component {
         style={{
           boxSizing: "border-box",
           boxShadow: hover
-            ? `0 3px 8px 0 ${colors["text-light"]}`
-            : `0 1px 3px 0 ${colors["text-light"]}`,
+            ? `0 3px 8px 0 ${color("text-light")}`
+            : `0 1px 3px 0 ${color("text-light")}`,
           height: 340,
         }}
         onMouseOver={() => this.setState({ hover: true })}
diff --git a/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx b/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx
index 2cb805d650ac1b7f84977894197944efdee77ba7..b50cf23b87a11f5de2d3d8815f76ccf85a396170 100644
--- a/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx
+++ b/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx
@@ -5,16 +5,16 @@ import PropTypes from "prop-types";
 import { connect } from "react-redux";
 import { t } from "ttag";
 
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import DateSingleWidget from "./widgets/DateSingleWidget.jsx";
-import DateRangeWidget from "./widgets/DateRangeWidget.jsx";
-import DateRelativeWidget from "./widgets/DateRelativeWidget.jsx";
-import DateMonthYearWidget from "./widgets/DateMonthYearWidget.jsx";
-import DateQuarterYearWidget from "./widgets/DateQuarterYearWidget.jsx";
-import DateAllOptionsWidget from "./widgets/DateAllOptionsWidget.jsx";
-import CategoryWidget from "./widgets/CategoryWidget.jsx";
-import TextWidget from "./widgets/TextWidget.jsx";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import Icon from "metabase/components/Icon";
+import DateSingleWidget from "./widgets/DateSingleWidget";
+import DateRangeWidget from "./widgets/DateRangeWidget";
+import DateRelativeWidget from "./widgets/DateRelativeWidget";
+import DateMonthYearWidget from "./widgets/DateMonthYearWidget";
+import DateQuarterYearWidget from "./widgets/DateQuarterYearWidget";
+import DateAllOptionsWidget from "./widgets/DateAllOptionsWidget";
+import CategoryWidget from "./widgets/CategoryWidget";
+import TextWidget from "./widgets/TextWidget";
 import ParameterFieldWidget from "./widgets/ParameterFieldWidget";
 
 import { fetchField, fetchFieldValues } from "metabase/redux/metadata";
diff --git a/frontend/src/metabase/parameters/components/ParameterWidget.jsx b/frontend/src/metabase/parameters/components/ParameterWidget.jsx
index 69215f0f77e248d7f5d8a04b811e616db54d839e..3298b9cbd6fb4948bb1e7688390168e8146ce208 100644
--- a/frontend/src/metabase/parameters/components/ParameterWidget.jsx
+++ b/frontend/src/metabase/parameters/components/ParameterWidget.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import ParameterValueWidget from "./ParameterValueWidget.jsx";
-import Icon from "metabase/components/Icon.jsx";
+import ParameterValueWidget from "./ParameterValueWidget";
+import Icon from "metabase/components/Icon";
 
 import S from "./ParameterWidget.css";
 import cx from "classnames";
diff --git a/frontend/src/metabase/parameters/components/Parameters.jsx b/frontend/src/metabase/parameters/components/Parameters.jsx
index 1dae670bb390ec0d04307514f40abb069c0f6de5..294fec3262c3d1b711affb4e99a82aaf2ddb2215 100644
--- a/frontend/src/metabase/parameters/components/Parameters.jsx
+++ b/frontend/src/metabase/parameters/components/Parameters.jsx
@@ -2,9 +2,9 @@
 
 import React, { Component } from "react";
 
-import StaticParameterWidget from "./ParameterWidget.jsx";
+import StaticParameterWidget from "./ParameterWidget";
 import Icon from "metabase/components/Icon";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import querystring from "querystring";
 import cx from "classnames";
@@ -215,7 +215,7 @@ const SortableParameterHandle = SortableHandle(() => (
   <div
     className="absolute top bottom left flex layout-centered hover-child cursor-grab"
     style={{
-      color: colors["border"],
+      color: color("border"),
       // width should match the left padding of the ParameterWidget container class so that it's centered
       width: "1em",
       marginLeft: "1px",
diff --git a/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx b/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx
index c2dbd3dec1ae2f69e4036e8907a8c078d609ee6c..da86242943bb523a8ca1444d9200fc18648ef8c8 100644
--- a/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx
@@ -8,7 +8,7 @@ import { t, ngettext, msgid } from "ttag";
 import { createMultiwordSearchRegex } from "metabase/lib/string";
 import { getHumanReadableValue } from "metabase/lib/query/field";
 
-import SelectPicker from "../../../query_builder/components/filters/pickers/SelectPicker.jsx";
+import SelectPicker from "../../../query_builder/components/filters/pickers/SelectPicker";
 
 type Props = {
   value: any,
diff --git a/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx
index 68f3e1924cbb7373a068c0cbac113d38eb3eca27..ab50aa71e0ca496ad55eb504a99561c3df8549cb 100644
--- a/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx
@@ -6,12 +6,12 @@ import { t } from "ttag";
 import DatePicker, {
   DATE_OPERATORS,
   getOperator,
-} from "metabase/query_builder/components/filters/pickers/DatePicker.jsx";
-import FilterOptions from "metabase/query_builder/components/filters/FilterOptions.jsx";
+} from "metabase/query_builder/components/filters/pickers/DatePicker";
+import FilterOptions from "metabase/query_builder/components/filters/FilterOptions";
 import { generateTimeFilterValuesDescriptions } from "metabase/lib/query_time";
 import { dateParameterValueToMBQL } from "metabase/meta/Parameter";
 
-import type { OperatorName } from "metabase/query_builder/components/filters/pickers/DatePicker.jsx";
+import type { OperatorName } from "metabase/query_builder/components/filters/pickers/DatePicker";
 import type { FieldFilter } from "metabase/meta/types/Query";
 
 type UrlEncoded = string;
diff --git a/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx
index 9e3dff80602ce859894940fd11b4d637862d4642..280971673708d991773688298a8df8b506e58ccc 100644
--- a/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx
@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 
-import YearPicker from "./YearPicker.jsx";
+import YearPicker from "./YearPicker";
 
 import moment from "moment";
 import _ from "underscore";
diff --git a/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx
index 7839a9bcce5785f2e9bffe56fa84ace430c09f2b..8663b4fdabbf4b66ff58d9d98db4b191d0ea255c 100644
--- a/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx
@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 
-import YearPicker from "./YearPicker.jsx";
+import YearPicker from "./YearPicker";
 
 import moment from "moment";
 import _ from "underscore";
diff --git a/frontend/src/metabase/parameters/components/widgets/DateRangeWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateRangeWidget.jsx
index dea2154ba46382b3b6b9cb170cc0b633ebb0e509..01d2674fc55144dbb059acb713be0f8bd7178894 100644
--- a/frontend/src/metabase/parameters/components/widgets/DateRangeWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/DateRangeWidget.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Calendar from "metabase/components/Calendar.jsx";
+import Calendar from "metabase/components/Calendar";
 import moment from "moment";
 
 const SEPARATOR = "~"; // URL-safe
diff --git a/frontend/src/metabase/parameters/components/widgets/DateSingleWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateSingleWidget.jsx
index c0fd941e13ab2e7fbd19dedc0d7a46e4a9b5fab6..22458ce368e8995b6937a7d4e2c07c8cc51a3fdf 100644
--- a/frontend/src/metabase/parameters/components/widgets/DateSingleWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/DateSingleWidget.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Calendar from "metabase/components/Calendar.jsx";
+import Calendar from "metabase/components/Calendar";
 import moment from "moment";
 
 const DateSingleWidget = ({ value, setValue, onClose }) => {
diff --git a/frontend/src/metabase/parameters/components/widgets/YearPicker.jsx b/frontend/src/metabase/parameters/components/widgets/YearPicker.jsx
index 861ec358d49b87f69b3fa619a2601d034d5f66a5..3b6ede05d5e8753564bbb5884803136b20081354 100644
--- a/frontend/src/metabase/parameters/components/widgets/YearPicker.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/YearPicker.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Select from "metabase/components/Select.jsx";
+import Select from "metabase/components/Select";
 import _ from "underscore";
 
 const YEARS = _.range(new Date().getFullYear(), 1900, -1);
diff --git a/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx b/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx
index 02f0a2b9d3e718840734bd333dbac899a459f7a8..6ff16344f584b57b2aa1844466ca04855aa5c528 100644
--- a/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx
+++ b/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx
@@ -9,7 +9,7 @@ import Button from "metabase/components/Button";
 import Parameters from "metabase/parameters/components/Parameters";
 import Select, { Option } from "metabase/components/Select";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import DisplayOptionsPane from "./DisplayOptionsPane";
 
@@ -88,7 +88,7 @@ const AdvancedSettingsPane = ({
             <Icon
               name={getIconForParameter(parameter)}
               className="mr2"
-              style={{ color: colors["text-light"] }}
+              style={{ color: color("text-light") }}
             />
             <h3>{parameter.name}</h3>
             <Select
diff --git a/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx b/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx
index f0ea3a949ae8f3b4eb42a8bb8b2c392345c9f32c..9be56e86a7393436bbdc97271aaf5d4b75c07cc3 100644
--- a/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx
+++ b/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx
@@ -16,7 +16,7 @@ import {
   getUnsignedPreviewUrl,
   getSignedToken,
 } from "metabase/public/lib/embed";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import {
   getSiteUrl,
@@ -179,7 +179,7 @@ export default class EmbedModalContent extends Component {
           style={{
             boxShadow:
               embedType === "application"
-                ? `0px 8px 15px -9px ${colors["text-dark"]}`
+                ? `0px 8px 15px -9px ${color("text-dark")}`
                 : undefined,
           }}
         >
diff --git a/frontend/src/metabase/pulse/components/PulseCardPreview.jsx b/frontend/src/metabase/pulse/components/PulseCardPreview.jsx
index bc864a0df867ccd3085bbeb740b50629fe940889..70a4ee0f09dd308f28a66bdebee1439ab5749082 100644
--- a/frontend/src/metabase/pulse/components/PulseCardPreview.jsx
+++ b/frontend/src/metabase/pulse/components/PulseCardPreview.jsx
@@ -3,13 +3,13 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Icon from "metabase/components/Icon.jsx";
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import Icon from "metabase/components/Icon";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
+import Tooltip from "metabase/components/Tooltip";
 
 import { t } from "ttag";
 import cx from "classnames";
-import colors, { alpha } from "metabase/lib/colors";
+import { color, alpha } from "metabase/lib/colors";
 
 export default class PulseCardPreview extends Component {
   constructor(props, context) {
@@ -80,7 +80,7 @@ export default class PulseCardPreview extends Component {
             top: 2,
             right: 2,
             background: `linear-gradient(to right, ${alpha(
-              colors["bg-white"],
+              color("bg-white"),
               0.2,
             )}, white, white)`,
             paddingLeft: 100,
@@ -179,7 +179,7 @@ const RenderedPulseCardPreviewHeader = ({ children }) => (
                 'Lato, "Helvetica Neue", Helvetica, Arial, sans-serif',
               fontSize: 16,
               fontWeight: 700,
-              color: colors["text-dark"],
+              color: color("text-dark"),
               textDecoration: "none",
             }}
           >
diff --git a/frontend/src/metabase/pulse/components/PulseEdit.jsx b/frontend/src/metabase/pulse/components/PulseEdit.jsx
index 8c03db90b28688c1b6e251ef264283a49ddbfbef..0557092493639b1cc71ef5f6489ae448f6706bff 100644
--- a/frontend/src/metabase/pulse/components/PulseEdit.jsx
+++ b/frontend/src/metabase/pulse/components/PulseEdit.jsx
@@ -3,19 +3,19 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t, jt, ngettext, msgid } from "ttag";
 
-import PulseEditName from "./PulseEditName.jsx";
+import PulseEditName from "./PulseEditName";
 import PulseEditCollection from "./PulseEditCollection";
-import PulseEditCards from "./PulseEditCards.jsx";
-import PulseEditChannels from "./PulseEditChannels.jsx";
-import PulseEditSkip from "./PulseEditSkip.jsx";
-import WhatsAPulse from "./WhatsAPulse.jsx";
+import PulseEditCards from "./PulseEditCards";
+import PulseEditChannels from "./PulseEditChannels";
+import PulseEditSkip from "./PulseEditSkip";
+import WhatsAPulse from "./WhatsAPulse";
 
-import ActionButton from "metabase/components/ActionButton.jsx";
+import ActionButton from "metabase/components/ActionButton";
 import Button from "metabase/components/Button";
 import MetabaseAnalytics from "metabase/lib/analytics";
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
-import ModalContent from "metabase/components/ModalContent.jsx";
-import DeleteModalWithConfirm from "metabase/components/DeleteModalWithConfirm.jsx";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
+import ModalContent from "metabase/components/ModalContent";
+import DeleteModalWithConfirm from "metabase/components/DeleteModalWithConfirm";
 
 import { pulseIsValid, cleanPulse, emailIsEnabled } from "metabase/lib/pulse";
 import * as Urls from "metabase/lib/urls";
diff --git a/frontend/src/metabase/pulse/components/PulseEditCards.jsx b/frontend/src/metabase/pulse/components/PulseEditCards.jsx
index 943e0c7fd4d287356d62cf714bf335c5539d9ac5..6451e0c76305d5aa76ddc8a8ec766b07df80c677 100644
--- a/frontend/src/metabase/pulse/components/PulseEditCards.jsx
+++ b/frontend/src/metabase/pulse/components/PulseEditCards.jsx
@@ -4,13 +4,13 @@ import PropTypes from "prop-types";
 import { t } from "ttag";
 import cx from "classnames";
 
-import PulseCardPreview from "./PulseCardPreview.jsx";
+import PulseCardPreview from "./PulseCardPreview";
 
 import QuestionSelect from "metabase/containers/QuestionSelect";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const SOFT_LIMIT = 10;
 const HARD_LIMIT = 25;
@@ -169,7 +169,7 @@ export default class PulseEditCards extends Component {
                   className="my4 ml3"
                   style={{
                     width: 375,
-                    borderTop: `1px dashed ${colors["border"]}`,
+                    borderTop: `1px dashed ${color("border")}`,
                   }}
                 />
               )}
diff --git a/frontend/src/metabase/pulse/components/PulseEditChannels.jsx b/frontend/src/metabase/pulse/components/PulseEditChannels.jsx
index 03b5979bc792643bbd592a279c7755f338aac48c..a9ef407d7f11015c91c903719036cdd012854a9d 100644
--- a/frontend/src/metabase/pulse/components/PulseEditChannels.jsx
+++ b/frontend/src/metabase/pulse/components/PulseEditChannels.jsx
@@ -5,13 +5,13 @@ import _ from "underscore";
 import { assoc, assocIn } from "icepick";
 import { t } from "ttag";
 
-import RecipientPicker from "./RecipientPicker.jsx";
+import RecipientPicker from "./RecipientPicker";
 
-import SchedulePicker from "metabase/components/SchedulePicker.jsx";
-import ActionButton from "metabase/components/ActionButton.jsx";
-import Select, { Option } from "metabase/components/Select.jsx";
-import Toggle from "metabase/components/Toggle.jsx";
-import Icon from "metabase/components/Icon.jsx";
+import SchedulePicker from "metabase/components/SchedulePicker";
+import ActionButton from "metabase/components/ActionButton";
+import Select, { Option } from "metabase/components/Select";
+import Toggle from "metabase/components/Toggle";
+import Icon from "metabase/components/Icon";
 import ChannelSetupMessage from "metabase/components/ChannelSetupMessage";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
diff --git a/frontend/src/metabase/pulse/components/PulseEditSkip.jsx b/frontend/src/metabase/pulse/components/PulseEditSkip.jsx
index 02199fcb3896412032529c4fd6e7ac13a7a1d245..494f73adb5743d638e210b663ecee84264242392 100644
--- a/frontend/src/metabase/pulse/components/PulseEditSkip.jsx
+++ b/frontend/src/metabase/pulse/components/PulseEditSkip.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 
-import Toggle from "metabase/components/Toggle.jsx";
+import Toggle from "metabase/components/Toggle";
 
 export default class PulseEditSkip extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/pulse/containers/PulseEditApp.jsx b/frontend/src/metabase/pulse/containers/PulseEditApp.jsx
index f73bdfe93a6eb75a4274c85c082d718fc9eb197d..a0e21d32b05c9d4097f758eb3c0eda3380932a99 100644
--- a/frontend/src/metabase/pulse/containers/PulseEditApp.jsx
+++ b/frontend/src/metabase/pulse/containers/PulseEditApp.jsx
@@ -4,7 +4,7 @@ import { connect } from "react-redux";
 
 import title from "metabase/hoc/Title";
 
-import PulseEdit from "../components/PulseEdit.jsx";
+import PulseEdit from "../components/PulseEdit";
 
 import Collections from "metabase/entities/collections";
 import Pulses from "metabase/entities/pulses";
diff --git a/frontend/src/metabase/query_builder/components/AddClauseButton.jsx b/frontend/src/metabase/query_builder/components/AddClauseButton.jsx
index fac84a957e902f97513baa4f3aeb9930761816d7..f9da920ec11b479942ef7623980f462169605880 100644
--- a/frontend/src/metabase/query_builder/components/AddClauseButton.jsx
+++ b/frontend/src/metabase/query_builder/components/AddClauseButton.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Icon from "metabase/components/Icon.jsx";
-import IconBorder from "metabase/components/IconBorder.jsx";
+import Icon from "metabase/components/Icon";
+import IconBorder from "metabase/components/IconBorder";
 
 export default class AddClauseButton extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/query_builder/components/AggregationPopover.jsx b/frontend/src/metabase/query_builder/components/AggregationPopover.jsx
index 5d7481d3e0f804f12b6aaca7a881308b54b0b7e0..930e3587c59e5d37ce04e468bf63022f036f2547 100644
--- a/frontend/src/metabase/query_builder/components/AggregationPopover.jsx
+++ b/frontend/src/metabase/query_builder/components/AggregationPopover.jsx
@@ -2,13 +2,13 @@ import React, { Component } from "react";
 import ReactDOM from "react-dom";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import AccordionList from "metabase/components/AccordionList.jsx";
-import FieldList from "./FieldList.jsx";
-import QueryDefinitionTooltip from "./QueryDefinitionTooltip.jsx";
+import AccordionList from "metabase/components/AccordionList";
+import FieldList from "./FieldList";
+import QueryDefinitionTooltip from "./QueryDefinitionTooltip";
 
-import Icon from "metabase/components/Icon.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
-import Button from "metabase/components/Button.jsx";
+import Icon from "metabase/components/Icon";
+import Tooltip from "metabase/components/Tooltip";
+import Button from "metabase/components/Button";
 
 import * as Q_DEPRECATED from "metabase/lib/query";
 import * as A_DEPRECATED from "metabase/lib/query_aggregation";
@@ -17,7 +17,7 @@ import Aggregation from "metabase-lib/lib/queries/structured/Aggregation";
 
 import _ from "underscore";
 
-import ExpressionEditorTextfield from "./expressions/ExpressionEditorTextfield.jsx";
+import ExpressionEditorTextfield from "./expressions/ExpressionEditorTextfield";
 
 const COMMON_SECTION_NAME = t`Common Metrics`;
 const BASIC_SECTION_NAME = t`Basic Metrics`;
diff --git a/frontend/src/metabase/query_builder/components/BreakoutName.jsx b/frontend/src/metabase/query_builder/components/BreakoutName.jsx
index a22f597a2ee15de20120b5faffbfaf197a8236b7..daeb69e711c4644efa8cd2f4e94bcaa3556b8504 100644
--- a/frontend/src/metabase/query_builder/components/BreakoutName.jsx
+++ b/frontend/src/metabase/query_builder/components/BreakoutName.jsx
@@ -5,7 +5,7 @@ import React from "react";
 import type { Breakout } from "metabase/meta/types/Query";
 import StructuredQuery from "metabase-lib/lib/queries/StructuredQuery";
 
-import FieldName from "./FieldName.jsx";
+import FieldName from "./FieldName";
 
 type Props = {
   breakout: Breakout,
diff --git a/frontend/src/metabase/query_builder/components/BreakoutPopover.jsx b/frontend/src/metabase/query_builder/components/BreakoutPopover.jsx
index de3a17ac6984c5a3d4bf12946c98a463091df777..b1f534b131afb341a6b90943246bd53e1f04f364 100644
--- a/frontend/src/metabase/query_builder/components/BreakoutPopover.jsx
+++ b/frontend/src/metabase/query_builder/components/BreakoutPopover.jsx
@@ -3,7 +3,7 @@
 import React from "react";
 import cx from "classnames";
 
-import FieldList from "metabase/query_builder/components/FieldList.jsx";
+import FieldList from "metabase/query_builder/components/FieldList";
 
 import type { Breakout } from "metabase/meta/types/Query";
 import type { FieldOptions } from "metabase/meta/types/Metadata";
diff --git a/frontend/src/metabase/query_builder/components/Clearable.jsx b/frontend/src/metabase/query_builder/components/Clearable.jsx
index 12c205e56ad92a14c18dd04b43a0beddbc1252eb..ca2e03a26df3dfe73d756a2c5ee365171715c88c 100644
--- a/frontend/src/metabase/query_builder/components/Clearable.jsx
+++ b/frontend/src/metabase/query_builder/components/Clearable.jsx
@@ -1,7 +1,7 @@
 import React from "react";
 import cx from "classnames";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const Clearable = ({ onClear, children, className }) => (
   <span className={cx("flex align-center", className)}>
diff --git a/frontend/src/metabase/query_builder/components/DataSelector.jsx b/frontend/src/metabase/query_builder/components/DataSelector.jsx
index 4477bb61d8fec0fb9912b985a10048a84a290d1a..2343d97f83c5c4b1c946e8c94bc6c07012a20ec3 100644
--- a/frontend/src/metabase/query_builder/components/DataSelector.jsx
+++ b/frontend/src/metabase/query_builder/components/DataSelector.jsx
@@ -3,9 +3,10 @@ import { connect } from "react-redux";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 import cx from "classnames";
-import Icon from "metabase/components/Icon.jsx";
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import AccordionList from "metabase/components/AccordionList.jsx";
+
+import Icon from "metabase/components/Icon";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import AccordionList from "metabase/components/AccordionList";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
 import { isQueryable } from "metabase/lib/table";
diff --git a/frontend/src/metabase/query_builder/components/ExtendedOptions.jsx b/frontend/src/metabase/query_builder/components/ExtendedOptions.jsx
index 86d2e7e0a0a32592bf1982b6961777c8eb501297..fe9f18b1e657e77bb3aa97596668eb3cfdca6120 100644
--- a/frontend/src/metabase/query_builder/components/ExtendedOptions.jsx
+++ b/frontend/src/metabase/query_builder/components/ExtendedOptions.jsx
@@ -5,12 +5,12 @@ import PropTypes from "prop-types";
 import _ from "underscore";
 import cx from "classnames";
 import { t } from "ttag";
-import AddClauseButton from "./AddClauseButton.jsx";
-import Expressions from "./expressions/Expressions.jsx";
-import ExpressionWidget from "./expressions/ExpressionWidget.jsx";
-import LimitWidget from "./LimitWidget.jsx";
-import SortWidget from "./SortWidget.jsx";
-import Popover from "metabase/components/Popover.jsx";
+import AddClauseButton from "./AddClauseButton";
+import Expressions from "./expressions/Expressions";
+import ExpressionWidget from "./expressions/ExpressionWidget";
+import LimitWidget from "./LimitWidget";
+import SortWidget from "./SortWidget";
+import Popover from "metabase/components/Popover";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
 
diff --git a/frontend/src/metabase/query_builder/components/FieldName.jsx b/frontend/src/metabase/query_builder/components/FieldName.jsx
index 54fb72d05d4a05db9663fe87b965bc426efccf21..35c5c8393b383f08216b435f6161e5677336b911 100644
--- a/frontend/src/metabase/query_builder/components/FieldName.jsx
+++ b/frontend/src/metabase/query_builder/components/FieldName.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import Clearable from "./Clearable.jsx";
+import Clearable from "./Clearable";
 
 import * as Q_DEPRECATED from "metabase/lib/query";
 
diff --git a/frontend/src/metabase/query_builder/components/FieldWidget.jsx b/frontend/src/metabase/query_builder/components/FieldWidget.jsx
index a09cea344786b0a5b2af5ff8181c47ec6314fec0..f113a20652da18e179e13e5761ac929913941d2a 100644
--- a/frontend/src/metabase/query_builder/components/FieldWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/FieldWidget.jsx
@@ -1,9 +1,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import FieldList from "./FieldList.jsx";
-import FieldName from "./FieldName.jsx";
-import Popover from "metabase/components/Popover.jsx";
+import FieldList from "./FieldList";
+import FieldName from "./FieldName";
+import Popover from "metabase/components/Popover";
 
 import * as Q_DEPRECATED from "metabase/lib/query";
 
diff --git a/frontend/src/metabase/query_builder/components/Filter.jsx b/frontend/src/metabase/query_builder/components/Filter.jsx
index 3e051eea0944c220c295f8d689c75b805e216e9e..c099521e49565c2640f7ac953d4e4b3ba77de0ee 100644
--- a/frontend/src/metabase/query_builder/components/Filter.jsx
+++ b/frontend/src/metabase/query_builder/components/Filter.jsx
@@ -2,7 +2,7 @@
 
 import React from "react";
 
-import FieldName from "./FieldName.jsx";
+import FieldName from "./FieldName";
 import Value from "metabase/components/Value";
 
 import Dimension from "metabase-lib/lib/Dimension";
diff --git a/frontend/src/metabase/query_builder/components/FilterList.jsx b/frontend/src/metabase/query_builder/components/FilterList.jsx
index 8b6f9b76755cf54d45aaf8e98cdde23cb6b6c052..00d179a67b673b449fc47e82e02e10055a7806c0 100644
--- a/frontend/src/metabase/query_builder/components/FilterList.jsx
+++ b/frontend/src/metabase/query_builder/components/FilterList.jsx
@@ -3,7 +3,7 @@
 import React, { Component } from "react";
 import { connect } from "react-redux";
 
-import Filter from "./Filter.jsx";
+import Filter from "./Filter";
 import { filterWidgetFilterRenderer } from "./filters/FilterWidget";
 
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/query_builder/components/GuiQueryEditor.jsx b/frontend/src/metabase/query_builder/components/GuiQueryEditor.jsx
index 4928ab55394f6f970a1286f09e89d83be58a98be..a1fc8cca54c83d6701a1bbc5ce94618d308a66af 100644
--- a/frontend/src/metabase/query_builder/components/GuiQueryEditor.jsx
+++ b/frontend/src/metabase/query_builder/components/GuiQueryEditor.jsx
@@ -5,14 +5,14 @@ import PropTypes from "prop-types";
 import ReactDOM from "react-dom";
 import { t } from "ttag";
 
-import AggregationWidget from "./AggregationWidget.jsx";
-import BreakoutWidget from "./BreakoutWidget.jsx";
-import ExtendedOptions from "./ExtendedOptions.jsx";
-import FilterWidgetList from "./filters/FilterWidgetList.jsx";
-import FilterPopover from "./filters/FilterPopover.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import IconBorder from "metabase/components/IconBorder.jsx";
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
+import AggregationWidget from "./AggregationWidget";
+import BreakoutWidget from "./BreakoutWidget";
+import ExtendedOptions from "./ExtendedOptions";
+import FilterWidgetList from "./filters/FilterWidgetList";
+import FilterPopover from "./filters/FilterPopover";
+import Icon from "metabase/components/Icon";
+import IconBorder from "metabase/components/IconBorder";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
 import { DatabaseSchemaAndTableDataSelector } from "metabase/query_builder/components/DataSelector";
 
 import cx from "classnames";
diff --git a/frontend/src/metabase/query_builder/components/QueryDefinitionTooltip.jsx b/frontend/src/metabase/query_builder/components/QueryDefinitionTooltip.jsx
index 7e0c7c5b90b6d60ff8a863c143e74b731ca4ee20..0ad1278799979c6d9008a39fa6a65d36cc628985 100644
--- a/frontend/src/metabase/query_builder/components/QueryDefinitionTooltip.jsx
+++ b/frontend/src/metabase/query_builder/components/QueryDefinitionTooltip.jsx
@@ -1,9 +1,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import FilterList from "./FilterList.jsx";
-import AggregationName from "./AggregationName.jsx";
-import FieldSet from "metabase/components/FieldSet.jsx";
+import FilterList from "./FilterList";
+import AggregationName from "./AggregationName";
+import FieldSet from "metabase/components/FieldSet";
 
 import * as Q_DEPRECATED from "metabase/lib/query";
 import { t } from "ttag";
diff --git a/frontend/src/metabase/query_builder/components/QueryDownloadWidget.jsx b/frontend/src/metabase/query_builder/components/QueryDownloadWidget.jsx
index 64cd10dc127267252337b983755d3d213210c25f..5decc7d726f3d21698da159954cc697a9ba0f3d9 100644
--- a/frontend/src/metabase/query_builder/components/QueryDownloadWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/QueryDownloadWidget.jsx
@@ -6,10 +6,10 @@ import { t } from "ttag";
 import { parse as urlParse } from "url";
 import querystring from "querystring";
 
-import PopoverWithTrigger from "metabase/components/PopoverWithTrigger.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import DownloadButton from "metabase/components/DownloadButton.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
+import Icon from "metabase/components/Icon";
+import DownloadButton from "metabase/components/DownloadButton";
+import Tooltip from "metabase/components/Tooltip";
 
 import * as Urls from "metabase/lib/urls";
 
diff --git a/frontend/src/metabase/query_builder/components/SavedQuestionIntroModal.jsx b/frontend/src/metabase/query_builder/components/SavedQuestionIntroModal.jsx
index 8a97461d25592297b8dd615bdec3bf6bef63115c..b85d7bf68e1125f5a09b4c83fd8723a90c2af8a7 100644
--- a/frontend/src/metabase/query_builder/components/SavedQuestionIntroModal.jsx
+++ b/frontend/src/metabase/query_builder/components/SavedQuestionIntroModal.jsx
@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 
-import Modal from "metabase/components/Modal.jsx";
+import Modal from "metabase/components/Modal";
 import { t } from "ttag";
 
 export default class SavedQuestionIntroModal extends Component {
diff --git a/frontend/src/metabase/query_builder/components/SelectionModule.jsx b/frontend/src/metabase/query_builder/components/SelectionModule.jsx
index 9f410efb100d3d34918759a07a0b0e46546fb20c..f0fdd0929882ab02b6073b2d4a49f2c3469d379d 100644
--- a/frontend/src/metabase/query_builder/components/SelectionModule.jsx
+++ b/frontend/src/metabase/query_builder/components/SelectionModule.jsx
@@ -1,9 +1,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Popover from "metabase/components/Popover.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import SearchBar from "./SearchBar.jsx";
+import Popover from "metabase/components/Popover";
+import Icon from "metabase/components/Icon";
+import SearchBar from "./SearchBar";
 import { t } from "ttag";
 import _ from "underscore";
 import cx from "classnames";
diff --git a/frontend/src/metabase/query_builder/components/SortWidget.jsx b/frontend/src/metabase/query_builder/components/SortWidget.jsx
index ba9d5511d5a99daf370447ed0418f7b1d89fd4fe..ec8af3c297d22616caa69c50ab9dab9fcd655011 100644
--- a/frontend/src/metabase/query_builder/components/SortWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/SortWidget.jsx
@@ -1,9 +1,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import Icon from "metabase/components/Icon.jsx";
-import FieldWidget from "./FieldWidget.jsx";
-import SelectionModule from "./SelectionModule.jsx";
+import Icon from "metabase/components/Icon";
+import FieldWidget from "./FieldWidget";
+import SelectionModule from "./SelectionModule";
 
 import _ from "underscore";
 
diff --git a/frontend/src/metabase/query_builder/components/TimeGroupingPopover.jsx b/frontend/src/metabase/query_builder/components/TimeGroupingPopover.jsx
index e43ae0ebd784a57089f417bf2147ee7948f3ef17..6a846e4e4ca4728909453ed9312fedb6555b1e64 100644
--- a/frontend/src/metabase/query_builder/components/TimeGroupingPopover.jsx
+++ b/frontend/src/metabase/query_builder/components/TimeGroupingPopover.jsx
@@ -62,7 +62,6 @@ export default class TimeGroupingPopover extends Component {
     this.props.onFieldChange([
       "datetime-field",
       this.props.field[1],
-      "as",
       bucketing,
     ]);
   }
diff --git a/frontend/src/metabase/query_builder/components/VisualizationResult.jsx b/frontend/src/metabase/query_builder/components/VisualizationResult.jsx
index ec02d3f0c517c20163fa4d67138001b43645b511..3d88ad30e66cbf32f82cd727ab835d4039323480 100644
--- a/frontend/src/metabase/query_builder/components/VisualizationResult.jsx
+++ b/frontend/src/metabase/query_builder/components/VisualizationResult.jsx
@@ -5,7 +5,7 @@ import { t, jt } from "ttag";
 import cx from "classnames";
 
 import ErrorMessage from "metabase/components/ErrorMessage";
-import Visualization from "metabase/visualizations/components/Visualization.jsx";
+import Visualization from "metabase/visualizations/components/Visualization";
 import { datasetContainsNoResults } from "metabase/lib/dataset";
 import { DatasetQuery } from "metabase/meta/types/Card";
 import { CreateAlertModalContent } from "metabase/query_builder/components/AlertModals";
diff --git a/frontend/src/metabase/query_builder/components/dataref/DatabasePane.jsx b/frontend/src/metabase/query_builder/components/dataref/DatabasePane.jsx
index 7cfc60f4fc697351c2e5f2ff7f59e43f0a181fb5..fc7c71cdaf95d951915cbafd63c38d44e6cca535 100644
--- a/frontend/src/metabase/query_builder/components/dataref/DatabasePane.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/DatabasePane.jsx
@@ -2,7 +2,7 @@
 import React from "react";
 import PropTypes from "prop-types";
 import { isQueryable } from "metabase/lib/table";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const DatabasePane = ({ database, show, ...props }) => (
   <div>
diff --git a/frontend/src/metabase/query_builder/components/dataref/DetailPane.jsx b/frontend/src/metabase/query_builder/components/dataref/DetailPane.jsx
index 7051d51ce9c6ee7412be1b616d34fd68d60d1596..a9cb58f0ebe41d64a475d67d969619c938b7b994 100644
--- a/frontend/src/metabase/query_builder/components/dataref/DetailPane.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/DetailPane.jsx
@@ -3,8 +3,8 @@ import React from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 import cx from "classnames";
-import Icon from "metabase/components/Icon.jsx";
-import Card from "metabase/components/Card.jsx";
+import Icon from "metabase/components/Icon";
+import Card from "metabase/components/Card";
 
 const DetailPane = ({ name, description, extra, values }) => (
   <div className="ml1">
diff --git a/frontend/src/metabase/query_builder/components/dataref/FieldPane.jsx b/frontend/src/metabase/query_builder/components/dataref/FieldPane.jsx
index e6572aeefb04de8640ed0d74d7757f5e9a42eec9..e247dd9e67a465eba034f5320024bf90c41769d7 100644
--- a/frontend/src/metabase/query_builder/components/dataref/FieldPane.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/FieldPane.jsx
@@ -2,9 +2,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import DetailPane from "./DetailPane.jsx";
-import QueryButton from "metabase/components/QueryButton.jsx";
-import UseForButton from "./UseForButton.jsx";
+import DetailPane from "./DetailPane";
+import QueryButton from "metabase/components/QueryButton";
+import UseForButton from "./UseForButton";
 
 import { fetchTableMetadata, fetchFieldValues } from "metabase/redux/metadata";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/query_builder/components/dataref/MainPane.jsx b/frontend/src/metabase/query_builder/components/dataref/MainPane.jsx
index 2bfe87989f569faa6dc1eea4638fd8c17583bcd9..e55e6d5bc31e327824d5daa52b8a8168d6f484e9 100644
--- a/frontend/src/metabase/query_builder/components/dataref/MainPane.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/MainPane.jsx
@@ -2,7 +2,7 @@
 import React from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const MainPane = ({ databases, show }) => (
   <div>
diff --git a/frontend/src/metabase/query_builder/components/dataref/MetricPane.jsx b/frontend/src/metabase/query_builder/components/dataref/MetricPane.jsx
index eed81f60226743fca77f554121fb6242dd7bdc5b..e86174e8dea66754bc46505abce084840da07f5a 100644
--- a/frontend/src/metabase/query_builder/components/dataref/MetricPane.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/MetricPane.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import { connect } from "react-redux";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import DetailPane from "./DetailPane.jsx";
-import QueryButton from "metabase/components/QueryButton.jsx";
-import QueryDefinition from "./QueryDefinition.jsx";
+import DetailPane from "./DetailPane";
+import QueryButton from "metabase/components/QueryButton";
+import QueryDefinition from "./QueryDefinition";
 
 import { createCard } from "metabase/lib/card";
 import * as Q_DEPRECATED from "metabase/lib/query";
diff --git a/frontend/src/metabase/query_builder/components/dataref/QueryDefinition.jsx b/frontend/src/metabase/query_builder/components/dataref/QueryDefinition.jsx
index 15ed579116c49c2276ffdafc280f11152c3b34b5..4fe43231fbcc60e084a230266d596b9edd51ed43 100644
--- a/frontend/src/metabase/query_builder/components/dataref/QueryDefinition.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/QueryDefinition.jsx
@@ -1,7 +1,7 @@
 import React from "react";
 
-import FilterList from "../FilterList.jsx";
-import AggregationName from "../AggregationName.jsx";
+import FilterList from "../FilterList";
+import AggregationName from "../AggregationName";
 
 import Question from "metabase-lib/lib/Question";
 
diff --git a/frontend/src/metabase/query_builder/components/dataref/SegmentPane.jsx b/frontend/src/metabase/query_builder/components/dataref/SegmentPane.jsx
index 29f7c708f331ab880da778481c59511408109dae..323135b59a79b43271aad984134874468e37df5e 100644
--- a/frontend/src/metabase/query_builder/components/dataref/SegmentPane.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/SegmentPane.jsx
@@ -6,10 +6,10 @@ import { t } from "ttag";
 import { fetchTableMetadata } from "metabase/redux/metadata";
 import { getMetadata } from "metabase/selectors/metadata";
 
-import DetailPane from "./DetailPane.jsx";
-import QueryButton from "metabase/components/QueryButton.jsx";
-import UseForButton from "./UseForButton.jsx";
-import QueryDefinition from "./QueryDefinition.jsx";
+import DetailPane from "./DetailPane";
+import QueryButton from "metabase/components/QueryButton";
+import UseForButton from "./UseForButton";
+import QueryDefinition from "./QueryDefinition";
 
 import { createCard } from "metabase/lib/card";
 import * as Q_DEPRECATED from "metabase/lib/query";
diff --git a/frontend/src/metabase/query_builder/components/dataref/TablePane.jsx b/frontend/src/metabase/query_builder/components/dataref/TablePane.jsx
index 1742ac460b4d6937ada5a037ecd92327799f2595..ce9cc73e7c3ca1b75c8524f8d0c71ebb6c50fec8 100644
--- a/frontend/src/metabase/query_builder/components/dataref/TablePane.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/TablePane.jsx
@@ -3,10 +3,10 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
 import cx from "classnames";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 // components
-import Expandable from "metabase/components/Expandable.jsx";
+import Expandable from "metabase/components/Expandable";
 
 // lib
 import { createCard } from "metabase/lib/card";
diff --git a/frontend/src/metabase/query_builder/components/dataref/UseForButton.jsx b/frontend/src/metabase/query_builder/components/dataref/UseForButton.jsx
index c5a470013a53c9ed74d080179539fcb49e69ceb1..d46c5aa149a3645995c18fecbb8932c7fec86db6 100644
--- a/frontend/src/metabase/query_builder/components/dataref/UseForButton.jsx
+++ b/frontend/src/metabase/query_builder/components/dataref/UseForButton.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const UseForButton = ({ title, onClick }) => (
   <a
diff --git a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield.jsx b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield.jsx
index 413159b8b6c3c1b6e026140507dfb43a81b7737f..712e1b1f4f2c607cb3711ef4c97bb8b651de7f4f 100644
--- a/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield.jsx
+++ b/frontend/src/metabase/query_builder/components/expressions/ExpressionEditorTextfield.jsx
@@ -18,9 +18,9 @@ import {
   KEYCODE_DOWN,
 } from "metabase/lib/keyboard";
 
-import Popover from "metabase/components/Popover.jsx";
+import Popover from "metabase/components/Popover";
 
-import TokenizedInput from "./TokenizedInput.jsx";
+import TokenizedInput from "./TokenizedInput";
 
 import { isExpression } from "metabase/lib/expressions";
 
diff --git a/frontend/src/metabase/query_builder/components/expressions/ExpressionWidget.jsx b/frontend/src/metabase/query_builder/components/expressions/ExpressionWidget.jsx
index 61cd58fd17aeb5d0ab8758f72d236c281a720407..abfe751e8f46e4c2a9cf7aa17dfe480e2d4a8048 100644
--- a/frontend/src/metabase/query_builder/components/expressions/ExpressionWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/expressions/ExpressionWidget.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
 import { t } from "ttag";
-import ExpressionEditorTextfield from "./ExpressionEditorTextfield.jsx";
+import ExpressionEditorTextfield from "./ExpressionEditorTextfield";
 import { isExpression } from "metabase/lib/expressions";
 import MetabaseSettings from "metabase/lib/settings";
 
diff --git a/frontend/src/metabase/query_builder/components/expressions/Expressions.jsx b/frontend/src/metabase/query_builder/components/expressions/Expressions.jsx
index 98fbf590e48cc9b078a151254c29f7591e3caf50..024976759e2ebcd01c7ebccc10f7809965e46ca6 100644
--- a/frontend/src/metabase/query_builder/components/expressions/Expressions.jsx
+++ b/frontend/src/metabase/query_builder/components/expressions/Expressions.jsx
@@ -2,9 +2,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import _ from "underscore";
 import { t } from "ttag";
-import Icon from "metabase/components/Icon.jsx";
-import IconBorder from "metabase/components/IconBorder.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import Icon from "metabase/components/Icon";
+import IconBorder from "metabase/components/IconBorder";
+import Tooltip from "metabase/components/Tooltip";
 
 import { format } from "metabase/lib/expressions/formatter";
 
diff --git a/frontend/src/metabase/query_builder/components/expressions/TokenizedInput.jsx b/frontend/src/metabase/query_builder/components/expressions/TokenizedInput.jsx
index 370aaab0b14685a02a5a84d2080f28c381275c0a..7a454430d5d647e818a25b2d85133fab0cf3c897 100644
--- a/frontend/src/metabase/query_builder/components/expressions/TokenizedInput.jsx
+++ b/frontend/src/metabase/query_builder/components/expressions/TokenizedInput.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import ReactDOM from "react-dom";
 
-import TokenizedExpression from "./TokenizedExpression.jsx";
+import TokenizedExpression from "./TokenizedExpression";
 
 import {
   getCaretPosition,
diff --git a/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx b/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx
index b5aa4026744158b0e25b25570bfabc8c4ad1bf83..e6ceb9cf9b0b419f5f755ee44537310bd5d69efc 100644
--- a/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx
@@ -2,9 +2,9 @@
 
 import React, { Component } from "react";
 
-import Icon from "metabase/components/Icon.jsx";
-import Popover from "metabase/components/Popover.jsx";
-import FilterPopover from "./FilterPopover.jsx";
+import Icon from "metabase/components/Icon";
+import Popover from "metabase/components/Popover";
+import FilterPopover from "./FilterPopover";
 import Filter from "metabase/query_builder/components/Filter";
 
 import cx from "classnames";
diff --git a/frontend/src/metabase/query_builder/components/filters/FilterWidgetList.jsx b/frontend/src/metabase/query_builder/components/filters/FilterWidgetList.jsx
index b373fd5462577e7d91a8ab5cdc48e1b75569d47a..d759672554af54273e40873f3bc98b0bc930e2a4 100644
--- a/frontend/src/metabase/query_builder/components/filters/FilterWidgetList.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/FilterWidgetList.jsx
@@ -3,7 +3,7 @@
 import React, { Component } from "react";
 import { findDOMNode } from "react-dom";
 import { t } from "ttag";
-import FilterWidget from "./FilterWidget.jsx";
+import FilterWidget from "./FilterWidget";
 
 import StructuredQuery from "metabase-lib/lib/queries/StructuredQuery";
 import Filter from "metabase-lib/lib/queries/structured/Filter";
diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/HoursMinutesInput.jsx b/frontend/src/metabase/query_builder/components/filters/pickers/HoursMinutesInput.jsx
index d44eb475837568e3058d12472c231559be9e2d28..20e7dfd3d7e1803e8ad5b3edcf56757edc68f8ab 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/HoursMinutesInput.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/HoursMinutesInput.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import NumericInput from "metabase/components/NumericInput.jsx";
+import NumericInput from "metabase/components/NumericInput";
 import Icon from "metabase/components/Icon";
 
 import cx from "classnames";
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 cccc9deb59f8c1b118e7db430d345a8f39abd8b2..7d31a69b72ea5dedee2c5bf668d2f35b53717e5b 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/NumberPicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/NumberPicker.jsx
@@ -3,7 +3,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import TextPicker from "./TextPicker.jsx";
+import TextPicker from "./TextPicker";
 
 type Props = {
   values: Array<number | null>,
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 352c369d0340f6222851928029191bc2af9a1287..0f7773020d4e2b0c3dda8d245e6f90faa34e3b20 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/RelativeDatePicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/RelativeDatePicker.jsx
@@ -3,7 +3,7 @@
 import React, { Component } from "react";
 import cx from "classnames";
 
-import NumericInput from "metabase/components/NumericInput.jsx";
+import NumericInput from "metabase/components/NumericInput";
 import DateUnitSelector from "../DateUnitSelector";
 
 import { assoc } from "icepick";
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 77b1304b7ff41ff86969c27af9eb139fa99b3ea7..97ef93e0bcc452148c721309d3d205ccd69e5dd4 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/SelectPicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/SelectPicker.jsx
@@ -3,8 +3,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import CheckBox from "metabase/components/CheckBox.jsx";
-import ListSearchField from "metabase/components/ListSearchField.jsx";
+import CheckBox from "metabase/components/CheckBox";
+import ListSearchField from "metabase/components/ListSearchField";
 
 import { capitalize } from "metabase/lib/formatting";
 import { createMultiwordSearchRegex } from "metabase/lib/string";
diff --git a/frontend/src/metabase/query_builder/components/notebook/NotebookStep.jsx b/frontend/src/metabase/query_builder/components/notebook/NotebookStep.jsx
index c56a181ecf190de9c741fc3293ee7d0c176edc40..126a766414b7e9d586b974a6b3af771ddae7994f 100644
--- a/frontend/src/metabase/query_builder/components/notebook/NotebookStep.jsx
+++ b/frontend/src/metabase/query_builder/components/notebook/NotebookStep.jsx
@@ -3,7 +3,7 @@ import React from "react";
 import { t } from "ttag";
 import _ from "underscore";
 
-import colors, { lighten, darken } from "metabase/lib/colors";
+import { color as c, lighten, darken } from "metabase/lib/colors";
 
 import Tooltip from "metabase/components/Tooltip";
 import Icon from "metabase/components/Icon";
@@ -27,60 +27,60 @@ import LimitStep from "./steps/LimitStep";
 const STEP_UI = {
   data: {
     title: t`Data`,
-    color: colors["brand"],
+    color: c("brand"),
     component: DataStep,
   },
   join: {
     title: t`Join data`,
-    color: colors["brand"],
+    color: c("brand"),
     icon: "join_left_outer",
     component: JoinStep,
     priority: 1,
   },
   expression: {
     title: t`Custom column`,
-    color: colors["bg-dark"],
+    color: c("bg-dark"),
     icon: "add_data",
     component: ExpressionStep,
   },
   filter: {
     title: t`Filter`,
-    color: colors["accent7"],
+    color: c("accent7"),
     icon: "filter",
     component: FilterStep,
     priority: 10,
   },
   summarize: {
     title: t`Summarize`,
-    color: colors["accent1"],
+    color: c("accent1"),
     icon: "sum",
     component: SummarizeStep,
     priority: 5,
   },
   aggregate: {
     title: t`Aggregate`,
-    color: colors["accent1"],
+    color: c("accent1"),
     icon: "sum",
     component: AggregateStep,
     priority: 5,
   },
   breakout: {
     title: t`Breakout`,
-    color: colors["accent4"],
+    color: c("accent4"),
     icon: "segment",
     component: BreakoutStep,
     priority: 1,
   },
   sort: {
     title: t`Sort`,
-    color: colors["bg-dark"],
+    color: c("bg-dark"),
     icon: "smartscalar",
     component: SortStep,
     compact: true,
   },
   limit: {
     title: t`Row limit`,
-    color: colors["bg-dark"],
+    color: c("bg-dark"),
     icon: "list",
     component: LimitStep,
     compact: true,
@@ -182,7 +182,7 @@ export default class NotebookStep extends React.Component {
                   }
                   icon="play"
                   title={t`Preview`}
-                  color={colors["text-light"]}
+                  color={c("text-light")}
                   onClick={() => this.setState({ showPreview: true })}
                 />
               </Box>
@@ -205,12 +205,12 @@ export default class NotebookStep extends React.Component {
 
 const ColorButton = Button.extend`
   border: none;
-  color: ${({ color }) => (color ? color : colors["text-medium"])}
+  color: ${({ color }) => (color ? color : c("text-medium"))}
   background-color: ${({ color }) => (color ? lighten(color, 0.61) : null)};
   &:hover {
-    color: ${({ color }) => (color ? darken(color, 0.115) : colors["brand"])};
+    color: ${({ color }) => (color ? darken(color, 0.115) : color("brand"))};
     background-color: ${({ color }) =>
-      color ? lighten(color, 0.5) : lighten(colors["brand"], 0.61)};
+      color ? lighten(color, 0.5) : lighten(color("brand"), 0.61)};
   }
   transition: background 300ms;
 `;
diff --git a/frontend/src/metabase/query_builder/components/notebook/steps/SortStep.jsx b/frontend/src/metabase/query_builder/components/notebook/steps/SortStep.jsx
index 863f5865da4e3b2be789ada04c8056d8b5243e26..0466846beb9b980c1db7f62b7827c304ced4639e 100644
--- a/frontend/src/metabase/query_builder/components/notebook/steps/SortStep.jsx
+++ b/frontend/src/metabase/query_builder/components/notebook/steps/SortStep.jsx
@@ -54,7 +54,7 @@ const SortName = ({ sort, query }) => (
   <FieldName field={sort && sort[1]} query={query} />
 );
 
-import FieldList from "metabase/query_builder/components/FieldList.jsx";
+import FieldList from "metabase/query_builder/components/FieldList";
 
 import type { OrderBy } from "metabase/meta/types/Query";
 import type { FieldOptions } from "metabase/meta/types/Metadata";
diff --git a/frontend/src/metabase/query_builder/components/template_tags/TagEditorHelp.jsx b/frontend/src/metabase/query_builder/components/template_tags/TagEditorHelp.jsx
index f373ab7ee386a5890947e560acc4b7641afdd4ee..d708dd4fcffe19e72ac2db480e399687f8c0ded0 100644
--- a/frontend/src/metabase/query_builder/components/template_tags/TagEditorHelp.jsx
+++ b/frontend/src/metabase/query_builder/components/template_tags/TagEditorHelp.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 import { t, jt } from "ttag";
-import Code from "metabase/components/Code.jsx";
+import Code from "metabase/components/Code";
 import MetabaseSettings from "metabase/lib/settings";
 
 const EXAMPLES = {
diff --git a/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.jsx b/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.jsx
index ee34b3f115c0e536c70e627ee76e5b97403b93b9..23c4e291ac39fe88a1dcc7bfebae64043ddb86df 100644
--- a/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.jsx
+++ b/frontend/src/metabase/query_builder/components/template_tags/TagEditorParam.jsx
@@ -4,10 +4,10 @@ import _ from "underscore";
 import { connect } from "react-redux";
 import { Link } from "react-router";
 
-import Toggle from "metabase/components/Toggle.jsx";
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
-import Select, { Option } from "metabase/components/Select.jsx";
-import ParameterValueWidget from "metabase/parameters/components/ParameterValueWidget.jsx";
+import Toggle from "metabase/components/Toggle";
+import InputBlurChange from "metabase/components/InputBlurChange";
+import Select, { Option } from "metabase/components/Select";
+import ParameterValueWidget from "metabase/parameters/components/ParameterValueWidget";
 
 import { parameterOptionsForField } from "metabase/meta/Dashboard";
 import type { TemplateTag } from "metabase/meta/types/Query";
diff --git a/frontend/src/metabase/query_builder/components/view/QuestionSummaries.jsx b/frontend/src/metabase/query_builder/components/view/QuestionSummaries.jsx
index 43690b15676b6ca90cd5d79a0244082b9acb1707..893b9d4977bd463c10e6c87f8a7804c47aecfad6 100644
--- a/frontend/src/metabase/query_builder/components/view/QuestionSummaries.jsx
+++ b/frontend/src/metabase/query_builder/components/view/QuestionSummaries.jsx
@@ -8,17 +8,17 @@ import ViewButton from "./ViewButton";
 
 import SummarizeSidebar from "./sidebars/SummarizeSidebar";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const SummarizePill = props => (
-  <ViewPill icon="insight" color={colors["accent1"]} {...props} />
+  <ViewPill icon="insight" color={color("accent1")} {...props} />
 );
 
 const SummarizeButton = props => (
   <ViewButton
     medium
     icon="insight"
-    color={colors["accent1"]}
+    color={color("accent1")}
     labelBreakpoint="sm"
     {...props}
   />
diff --git a/frontend/src/metabase/query_builder/components/view/ViewButton.jsx b/frontend/src/metabase/query_builder/components/view/ViewButton.jsx
index da627bfe73a8e7f0471ff219542b6e9d9f012515..1f027f3e940f9334ef91e39f26802165d89250e3 100644
--- a/frontend/src/metabase/query_builder/components/view/ViewButton.jsx
+++ b/frontend/src/metabase/query_builder/components/view/ViewButton.jsx
@@ -1,5 +1,5 @@
 import Button from "metabase/components/Button";
-import colors, { alpha } from "metabase/lib/colors";
+import { color, alpha } from "metabase/lib/colors";
 
 import styled from "styled-components";
 
@@ -20,7 +20,7 @@ const ViewButton = styled(Button)`
   }
 `;
 ViewButton.defaultProps = {
-  color: colors["brand"],
+  color: color("brand"),
 };
 
 export default ViewButton;
diff --git a/frontend/src/metabase/query_builder/components/view/ViewFooter.jsx b/frontend/src/metabase/query_builder/components/view/ViewFooter.jsx
index d68e2e60f0db21e83ef86fe5b98a608c958d4c6e..12813fa76111d24427b36919b39e1a2438c12a98 100644
--- a/frontend/src/metabase/query_builder/components/view/ViewFooter.jsx
+++ b/frontend/src/metabase/query_builder/components/view/ViewFooter.jsx
@@ -4,7 +4,7 @@ import { t } from "ttag";
 import cx from "classnames";
 import styled from "styled-components";
 import { Flex } from "grid-styled";
-import colors, { darken } from "metabase/lib/colors";
+import { color, darken } from "metabase/lib/colors";
 
 import Icon from "metabase/components/Icon";
 
@@ -201,7 +201,7 @@ const VizSettingsButton = ({ ...props }) => (
 const Well = styled(Flex)`
   border-radius: 99px;
   &:hover {
-    background-color: ${darken(colors["bg-medium"], 0.05)};
+    background-color: ${darken(color("bg-medium"), 0.05)};
   }
   transition: background 300ms linear;
 `;
@@ -210,13 +210,12 @@ Well.defaultProps = {
   px: "6px",
   py: "4px",
   align: "center",
-  bg: colors["bg-medium"],
+  bg: color("bg-medium"),
 };
 
 const ToggleIcon = styled(Flex)`
   cursor: pointer;
-  background-color: ${props =>
-    props.active ? colors["brand"] : "transparent"};
+  background-color: ${props => (props.active ? color("brand") : "transparent")};
   color: ${props => (props.active ? "white" : "inherit")};
   border-radius: 99px;
 `;
diff --git a/frontend/src/metabase/query_builder/components/view/ViewPill.jsx b/frontend/src/metabase/query_builder/components/view/ViewPill.jsx
index 9c9d9e6d12693b5a58b7c685416fa833ddfc9d29..02dc18c119647fa924197354cd3424c26c9051d3 100644
--- a/frontend/src/metabase/query_builder/components/view/ViewPill.jsx
+++ b/frontend/src/metabase/query_builder/components/view/ViewPill.jsx
@@ -1,13 +1,13 @@
 import React from "react";
 
 import Icon from "metabase/components/Icon";
-import colors, { alpha } from "metabase/lib/colors";
+import { color as c, alpha } from "metabase/lib/colors";
 import cx from "classnames";
 
 export default function ViewPill({
   className,
   style = {},
-  color = colors["brand"],
+  color = c("brand"),
   invert,
   children,
   onClick,
diff --git a/frontend/src/metabase/questions/containers/AddToDashboard.jsx b/frontend/src/metabase/questions/containers/AddToDashboard.jsx
index acb81b2921c7df858a285e20e04f23480eb715fc..117457f3403fcc608f4ed27528a9bdef88160ef9 100644
--- a/frontend/src/metabase/questions/containers/AddToDashboard.jsx
+++ b/frontend/src/metabase/questions/containers/AddToDashboard.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import { t } from "ttag";
 
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalContent from "metabase/components/ModalContent";
 import QuestionPicker from "metabase/containers/QuestionPicker";
 
 export default class AddToDashboard extends Component {
diff --git a/frontend/src/metabase/reference/components/EditButton.jsx b/frontend/src/metabase/reference/components/EditButton.jsx
index f0686968f6946474d1cffc6900096a3a42f37c5e..3084e652c411833855c7d39ee81cc5b41ab69a5b 100644
--- a/frontend/src/metabase/reference/components/EditButton.jsx
+++ b/frontend/src/metabase/reference/components/EditButton.jsx
@@ -5,7 +5,7 @@ import pure from "recompose/pure";
 import { t } from "ttag";
 import S from "./EditButton.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const EditButton = ({ className, startEditing }) => (
   <button
diff --git a/frontend/src/metabase/reference/components/EditHeader.jsx b/frontend/src/metabase/reference/components/EditHeader.jsx
index 35d2f4b0a1425387bae384d35515db59e2bc17f9..4d24715dddec36c8470ed11cee5acf6c28e44e8b 100644
--- a/frontend/src/metabase/reference/components/EditHeader.jsx
+++ b/frontend/src/metabase/reference/components/EditHeader.jsx
@@ -5,7 +5,7 @@ import pure from "recompose/pure";
 import { t } from "ttag";
 import S from "./EditHeader.css";
 
-import RevisionMessageModal from "metabase/reference/components/RevisionMessageModal.jsx";
+import RevisionMessageModal from "metabase/reference/components/RevisionMessageModal";
 
 const EditHeader = ({
   hasRevisionHistory,
diff --git a/frontend/src/metabase/reference/components/EditableReferenceHeader.jsx b/frontend/src/metabase/reference/components/EditableReferenceHeader.jsx
index 590927dec648215e908c4ef7dedbffb1a0f7ccbc..2916bb830fa643e1273098ee2e38e85761285f3e 100644
--- a/frontend/src/metabase/reference/components/EditableReferenceHeader.jsx
+++ b/frontend/src/metabase/reference/components/EditableReferenceHeader.jsx
@@ -8,13 +8,13 @@ import S from "./ReferenceHeader.css";
 import L from "metabase/components/List.css";
 import E from "metabase/reference/components/EditButton.css";
 
-import IconBorder from "metabase/components/IconBorder.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
-import Ellipsified from "metabase/components/Ellipsified.jsx";
-import EditButton from "metabase/reference/components/EditButton.jsx";
+import IconBorder from "metabase/components/IconBorder";
+import Icon from "metabase/components/Icon";
+import InputBlurChange from "metabase/components/InputBlurChange";
+import Ellipsified from "metabase/components/Ellipsified";
+import EditButton from "metabase/reference/components/EditButton";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const EditableReferenceHeader = ({
   entity = {},
@@ -40,7 +40,7 @@ const EditableReferenceHeader = ({
         {headerIcon && (
           <IconBorder
             borderWidth="0"
-            style={{ backgroundColor: colors["bg-medium"] }}
+            style={{ backgroundColor: color("bg-medium") }}
           >
             <Icon
               className="text-brand"
diff --git a/frontend/src/metabase/reference/components/Field.jsx b/frontend/src/metabase/reference/components/Field.jsx
index 63db960d9bb8e4564e2c687ffb6047f64061041c..e7f8b0b1bbd6efc9aafcb0551a0a0141782a1420 100644
--- a/frontend/src/metabase/reference/components/Field.jsx
+++ b/frontend/src/metabase/reference/components/Field.jsx
@@ -12,8 +12,8 @@ import { getIn } from "icepick";
 import S from "metabase/components/List.css";
 import F from "./Field.css";
 
-import Select from "metabase/components/Select.jsx";
-import Icon from "metabase/components/Icon.jsx";
+import Select from "metabase/components/Select";
+import Icon from "metabase/components/Icon";
 
 import cx from "classnames";
 import pure from "recompose/pure";
diff --git a/frontend/src/metabase/reference/components/FieldToGroupBy.jsx b/frontend/src/metabase/reference/components/FieldToGroupBy.jsx
index e4d82c39e9d581e615caf3bad8e617f9d8656da5..6c56d7382075960af0db10a74a5a63a4a8fb2000 100644
--- a/frontend/src/metabase/reference/components/FieldToGroupBy.jsx
+++ b/frontend/src/metabase/reference/components/FieldToGroupBy.jsx
@@ -5,7 +5,7 @@ import { t } from "ttag";
 import S from "./FieldToGroupBy.css";
 import Q from "metabase/components/QueryButton.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const FieldToGroupBy = ({
   className,
diff --git a/frontend/src/metabase/reference/components/FieldTypeDetail.jsx b/frontend/src/metabase/reference/components/FieldTypeDetail.jsx
index a5ba51a17590f74953f109bd5d8866b700b61af2..266af6dee1540655f952651bc84c9d5de70c8427 100644
--- a/frontend/src/metabase/reference/components/FieldTypeDetail.jsx
+++ b/frontend/src/metabase/reference/components/FieldTypeDetail.jsx
@@ -8,7 +8,7 @@ import * as MetabaseCore from "metabase/lib/core";
 import { isNumericBaseType } from "metabase/lib/schema_metadata";
 import { isFK } from "metabase/lib/types";
 
-import Select from "metabase/components/Select.jsx";
+import Select from "metabase/components/Select";
 
 import D from "metabase/reference/components/Detail.css";
 
diff --git a/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx b/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
index f3bd75f4bffeaf491c1eee55e6b16c662d9cebda..4c224589e04a7eb6b963cc75f3e1dfa1a6876f06 100644
--- a/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
+++ b/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
@@ -8,7 +8,7 @@ import L from "metabase/components/List.css";
 
 import { getQuestionUrl } from "../utils";
 
-import FieldToGroupBy from "metabase/reference/components/FieldToGroupBy.jsx";
+import FieldToGroupBy from "metabase/reference/components/FieldToGroupBy";
 
 import { fetchTableMetadata } from "metabase/redux/metadata";
 import { getMetadata } from "metabase/selectors/metadata";
diff --git a/frontend/src/metabase/reference/components/Formula.jsx b/frontend/src/metabase/reference/components/Formula.jsx
index ddd8e5eaf03d4cfd82f8b90a9ec1ad561b6b8968..34e717c7734f7e3c26e653f52b970d135cc63e99 100644
--- a/frontend/src/metabase/reference/components/Formula.jsx
+++ b/frontend/src/metabase/reference/components/Formula.jsx
@@ -6,9 +6,9 @@ import { CSSTransitionGroup } from "react-transition-group";
 
 import S from "./Formula.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
-import QueryDefinition from "metabase/query_builder/components/dataref/QueryDefinition.jsx";
+import QueryDefinition from "metabase/query_builder/components/dataref/QueryDefinition";
 import { fetchTableMetadata } from "metabase/redux/metadata";
 import { getMetadata } from "metabase/selectors/metadata";
 
diff --git a/frontend/src/metabase/reference/components/GuideDetailEditor.jsx b/frontend/src/metabase/reference/components/GuideDetailEditor.jsx
index d1bc126f5c6c17a230b7597442694810ee138dca..e917b34ac498bfdb8b9647717a86642e021a296d 100644
--- a/frontend/src/metabase/reference/components/GuideDetailEditor.jsx
+++ b/frontend/src/metabase/reference/components/GuideDetailEditor.jsx
@@ -6,9 +6,9 @@ import cx from "classnames";
 import { t } from "ttag";
 import S from "./GuideDetailEditor.css";
 
-import Select from "metabase/components/Select.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import Select from "metabase/components/Select";
+import Icon from "metabase/components/Icon";
+import Tooltip from "metabase/components/Tooltip";
 
 import { typeToBgClass } from "../utils.js";
 import { SchemaTableAndSegmentDataSelector } from "metabase/query_builder/components/DataSelector";
diff --git a/frontend/src/metabase/reference/components/GuideEditSection.jsx b/frontend/src/metabase/reference/components/GuideEditSection.jsx
index 7931724618cacd5f84cb529cd47b55cc01ccfe62..b42b16ee688ea3eb91b3392e0678253d285b1a3d 100644
--- a/frontend/src/metabase/reference/components/GuideEditSection.jsx
+++ b/frontend/src/metabase/reference/components/GuideEditSection.jsx
@@ -6,7 +6,7 @@ import cx from "classnames";
 
 import S from "./GuideEditSection.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 const GuideEditSection = ({
   children,
diff --git a/frontend/src/metabase/reference/components/GuideHeader.jsx b/frontend/src/metabase/reference/components/GuideHeader.jsx
index 80e9687f3e75e8dd964f8b368e7232a08b8a45da..bc4a732cb766727f2835ff7ce86c71ac7135a004 100644
--- a/frontend/src/metabase/reference/components/GuideHeader.jsx
+++ b/frontend/src/metabase/reference/components/GuideHeader.jsx
@@ -2,7 +2,7 @@ import React from "react";
 import PropTypes from "prop-types";
 import pure from "recompose/pure";
 import { t } from "ttag";
-import EditButton from "metabase/reference/components/EditButton.jsx";
+import EditButton from "metabase/reference/components/EditButton";
 
 const GuideHeader = ({ startEditing, isSuperuser }) => (
   <div>
diff --git a/frontend/src/metabase/reference/components/MetricImportantFieldsDetail.jsx b/frontend/src/metabase/reference/components/MetricImportantFieldsDetail.jsx
index 9ad8d1c1e07a75a2f2e42bfc5d3ca5a5cfeb576c..f666d6d50382fe3c11bb06177a9e78e5f3ecbe9d 100644
--- a/frontend/src/metabase/reference/components/MetricImportantFieldsDetail.jsx
+++ b/frontend/src/metabase/reference/components/MetricImportantFieldsDetail.jsx
@@ -3,9 +3,9 @@ import PropTypes from "prop-types";
 import cx from "classnames";
 import pure from "recompose/pure";
 import { t } from "ttag";
-import FieldsToGroupBy from "metabase/reference/components/FieldsToGroupBy.jsx";
+import FieldsToGroupBy from "metabase/reference/components/FieldsToGroupBy";
 
-import Select from "metabase/components/Select.jsx";
+import Select from "metabase/components/Select";
 
 import D from "metabase/reference/components/Detail.css";
 
diff --git a/frontend/src/metabase/reference/components/ReferenceHeader.jsx b/frontend/src/metabase/reference/components/ReferenceHeader.jsx
index 3042fba7264a1e1e785ccff4fff08a003331ffbb..390ecc28389157b4f8aa3c220150f4a0d91311a6 100644
--- a/frontend/src/metabase/reference/components/ReferenceHeader.jsx
+++ b/frontend/src/metabase/reference/components/ReferenceHeader.jsx
@@ -8,11 +8,11 @@ import S from "./ReferenceHeader.css";
 import L from "metabase/components/List.css";
 import E from "metabase/reference/components/EditButton.css";
 
-import IconBorder from "metabase/components/IconBorder.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import Ellipsified from "metabase/components/Ellipsified.jsx";
+import IconBorder from "metabase/components/IconBorder";
+import Icon from "metabase/components/Icon";
+import Ellipsified from "metabase/components/Ellipsified";
 import { t } from "ttag";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 const ReferenceHeader = ({
   name,
@@ -27,7 +27,7 @@ const ReferenceHeader = ({
         {headerIcon && (
           <IconBorder
             borderWidth="0"
-            style={{ backgroundColor: colors["bg-medium"] }}
+            style={{ backgroundColor: color("bg-medium") }}
           >
             <Icon
               className="text-brand"
diff --git a/frontend/src/metabase/reference/components/RevisionMessageModal.jsx b/frontend/src/metabase/reference/components/RevisionMessageModal.jsx
index 051c414dbfa7f2f8bb254446eb9338a0d1c47195..5f14fc2a51ee0e445d4e12734ee98b0a4f200f2d 100644
--- a/frontend/src/metabase/reference/components/RevisionMessageModal.jsx
+++ b/frontend/src/metabase/reference/components/RevisionMessageModal.jsx
@@ -2,8 +2,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import ModalWithTrigger from "metabase/components/ModalWithTrigger.jsx";
-import ModalContent from "metabase/components/ModalContent.jsx";
+import ModalWithTrigger from "metabase/components/ModalWithTrigger";
+import ModalContent from "metabase/components/ModalContent";
 
 import S from "./RevisionMessageModal.css";
 
diff --git a/frontend/src/metabase/reference/components/UsefulQuestions.jsx b/frontend/src/metabase/reference/components/UsefulQuestions.jsx
index dd1c183f80ab009a8982e69b2d2cd7be2480d3ee..9b81233d8c2f82e332aabf6f7a61511416eb57c2 100644
--- a/frontend/src/metabase/reference/components/UsefulQuestions.jsx
+++ b/frontend/src/metabase/reference/components/UsefulQuestions.jsx
@@ -7,7 +7,7 @@ import S from "./UsefulQuestions.css";
 import D from "metabase/reference/components/Detail.css";
 import L from "metabase/components/List.css";
 
-import QueryButton from "metabase/components/QueryButton.jsx";
+import QueryButton from "metabase/components/QueryButton";
 
 const UsefulQuestions = ({ questions }) => (
   <div className={cx(D.detail)}>
diff --git a/frontend/src/metabase/reference/databases/DatabaseDetail.jsx b/frontend/src/metabase/reference/databases/DatabaseDetail.jsx
index c157576e741c523175ffd2f56bd640c99e07c6ea..e2cbcfc52c49ed0c7da6b082f52650526d98216c 100644
--- a/frontend/src/metabase/reference/databases/DatabaseDetail.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseDetail.jsx
@@ -5,12 +5,12 @@ import { connect } from "react-redux";
 import { reduxForm } from "redux-form";
 import { push } from "react-router-redux";
 import { t } from "ttag";
-import List from "metabase/components/List.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import List from "metabase/components/List";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
-import Detail from "metabase/reference/components/Detail.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
+import Detail from "metabase/reference/components/Detail";
 
 import {
   getDatabase,
diff --git a/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx b/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx
index 825e7b5e2e58551a6766a2c741101d2c8254a771..28bf3d7d105d941211d7c0efe449ace9b5bdf466 100644
--- a/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseDetailContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import DatabaseSidebar from "./DatabaseSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import DatabaseDetail from "metabase/reference/databases/DatabaseDetail.jsx";
+import DatabaseSidebar from "./DatabaseSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import DatabaseDetail from "metabase/reference/databases/DatabaseDetail";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/DatabaseList.jsx b/frontend/src/metabase/reference/databases/DatabaseList.jsx
index 9f3fe64459a5b3de30a03d2b67d2b7a50de3dc87..43ac5312e083ed0237ee06d9a8ed3d237f8d7ad9 100644
--- a/frontend/src/metabase/reference/databases/DatabaseList.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseList.jsx
@@ -7,12 +7,12 @@ import { isQueryable } from "metabase/lib/table";
 
 import S from "metabase/components/List.css";
 
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 import { getDatabases, getError, getLoading } from "../selectors";
 
diff --git a/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx b/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx
index c3e824b00fc795ae167243f3f2e54c80f934231f..9fe2d1ffac5975a5ac62176cd616e44fdd75fc08 100644
--- a/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseListContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import BaseSidebar from "metabase/reference/guide/BaseSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import DatabaseList from "metabase/reference/databases/DatabaseList.jsx";
+import BaseSidebar from "metabase/reference/guide/BaseSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import DatabaseList from "metabase/reference/databases/DatabaseList";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/DatabaseSidebar.jsx b/frontend/src/metabase/reference/databases/DatabaseSidebar.jsx
index 62be7da78f870820bbfd0247874470a6ce738935..407d54dfa9a06f62eae51380cac6ab10a731e584 100644
--- a/frontend/src/metabase/reference/databases/DatabaseSidebar.jsx
+++ b/frontend/src/metabase/reference/databases/DatabaseSidebar.jsx
@@ -3,8 +3,8 @@ import React from "react";
 import PropTypes from "prop-types";
 import S from "metabase/components/Sidebar.css";
 import { t } from "ttag";
-import Breadcrumbs from "metabase/components/Breadcrumbs.jsx";
-import SidebarItem from "metabase/components/SidebarItem.jsx";
+import Breadcrumbs from "metabase/components/Breadcrumbs";
+import SidebarItem from "metabase/components/SidebarItem";
 
 import cx from "classnames";
 import pure from "recompose/pure";
diff --git a/frontend/src/metabase/reference/databases/FieldDetail.jsx b/frontend/src/metabase/reference/databases/FieldDetail.jsx
index 965a5bddb1225f273effac47a10eb324b7a168d4..1bf2814d2845611ce5ab0fd75cb6cbaabfd5e209 100644
--- a/frontend/src/metabase/reference/databases/FieldDetail.jsx
+++ b/frontend/src/metabase/reference/databases/FieldDetail.jsx
@@ -7,14 +7,14 @@ import { push } from "react-router-redux";
 import { t } from "ttag";
 import S from "metabase/reference/Reference.css";
 
-import List from "metabase/components/List.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import List from "metabase/components/List";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
-import Detail from "metabase/reference/components/Detail.jsx";
-import FieldTypeDetail from "metabase/reference/components/FieldTypeDetail.jsx";
-import UsefulQuestions from "metabase/reference/components/UsefulQuestions.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
+import Detail from "metabase/reference/components/Detail";
+import FieldTypeDetail from "metabase/reference/components/FieldTypeDetail";
+import UsefulQuestions from "metabase/reference/components/UsefulQuestions";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx b/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx
index f59a58c42c8fa4e32c184578d2ff0719cbe7d437..db134c057888ac8272f3a040da10344433dbde4a 100644
--- a/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx
+++ b/frontend/src/metabase/reference/databases/FieldDetailContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import FieldSidebar from "./FieldSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import FieldDetail from "metabase/reference/databases/FieldDetail.jsx";
+import FieldSidebar from "./FieldSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import FieldDetail from "metabase/reference/databases/FieldDetail";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/FieldList.jsx b/frontend/src/metabase/reference/databases/FieldList.jsx
index a3578d5a3bead3165adf7932fd5f60d69279e22a..afc32edb8fda6934c5eac15da61ea8052fa15dc5 100644
--- a/frontend/src/metabase/reference/databases/FieldList.jsx
+++ b/frontend/src/metabase/reference/databases/FieldList.jsx
@@ -8,13 +8,13 @@ import S from "metabase/components/List.css";
 import R from "metabase/reference/Reference.css";
 import F from "metabase/reference/components/Field.css";
 
-import Field from "metabase/reference/components/Field.jsx";
-import List from "metabase/components/List.jsx";
-import EmptyState from "metabase/components/EmptyState.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import Field from "metabase/reference/components/Field";
+import List from "metabase/components/List";
+import EmptyState from "metabase/components/EmptyState";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/reference/databases/FieldListContainer.jsx b/frontend/src/metabase/reference/databases/FieldListContainer.jsx
index a09c13b90efd51637c8d374f556c5ba2eb55eaed..228def21144d792c0e0d47e37c2d1d93799d18ba 100644
--- a/frontend/src/metabase/reference/databases/FieldListContainer.jsx
+++ b/frontend/src/metabase/reference/databases/FieldListContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import TableSidebar from "./TableSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import FieldList from "metabase/reference/databases/FieldList.jsx";
+import TableSidebar from "./TableSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import FieldList from "metabase/reference/databases/FieldList";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/TableDetail.jsx b/frontend/src/metabase/reference/databases/TableDetail.jsx
index 00be797c407c16e5ee5990cb3b55101abe8f2f36..5e8ef06843a3d72b7a29549ab1659957dafa5847 100644
--- a/frontend/src/metabase/reference/databases/TableDetail.jsx
+++ b/frontend/src/metabase/reference/databases/TableDetail.jsx
@@ -7,13 +7,13 @@ import { push } from "react-router-redux";
 import { t } from "ttag";
 import S from "metabase/reference/Reference.css";
 
-import List from "metabase/components/List.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import List from "metabase/components/List";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
-import Detail from "metabase/reference/components/Detail.jsx";
-import UsefulQuestions from "metabase/reference/components/UsefulQuestions.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
+import Detail from "metabase/reference/components/Detail";
+import UsefulQuestions from "metabase/reference/components/UsefulQuestions";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/databases/TableDetailContainer.jsx b/frontend/src/metabase/reference/databases/TableDetailContainer.jsx
index 065a2c125932b07e2a9b15d86e04dc2e3a8bbacd..3bda7bbfa585f72d9586c1ef9420b08806ff3aed 100644
--- a/frontend/src/metabase/reference/databases/TableDetailContainer.jsx
+++ b/frontend/src/metabase/reference/databases/TableDetailContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import TableSidebar from "./TableSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import TableDetail from "metabase/reference/databases/TableDetail.jsx";
+import TableSidebar from "./TableSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import TableDetail from "metabase/reference/databases/TableDetail";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/TableList.jsx b/frontend/src/metabase/reference/databases/TableList.jsx
index bed4382b90f0e110d8969dc0a7684c891b8ea5f3..61bd6ceb592fb746132517e36696f03eb362023c 100644
--- a/frontend/src/metabase/reference/databases/TableList.jsx
+++ b/frontend/src/metabase/reference/databases/TableList.jsx
@@ -8,13 +8,13 @@ import { isQueryable } from "metabase/lib/table";
 import S from "metabase/components/List.css";
 import R from "metabase/reference/Reference.css";
 
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
-import EmptyState from "metabase/components/EmptyState.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
+import EmptyState from "metabase/components/EmptyState";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 import {
   getDatabase,
diff --git a/frontend/src/metabase/reference/databases/TableListContainer.jsx b/frontend/src/metabase/reference/databases/TableListContainer.jsx
index be38499f2e09d573540062a57006f54f283ae79b..adb9538fed9f2bf00c34f8bff695ab1e71413ae7 100644
--- a/frontend/src/metabase/reference/databases/TableListContainer.jsx
+++ b/frontend/src/metabase/reference/databases/TableListContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import DatabaseSidebar from "./DatabaseSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import TableList from "metabase/reference/databases/TableList.jsx";
+import DatabaseSidebar from "./DatabaseSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import TableList from "metabase/reference/databases/TableList";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/databases/TableQuestions.jsx b/frontend/src/metabase/reference/databases/TableQuestions.jsx
index b38c643f9929c1ce33bcb72db7b1617cb65e2422..14c64cd9a3b6a45aa99b0bd74e53f8f6ff7fa846 100644
--- a/frontend/src/metabase/reference/databases/TableQuestions.jsx
+++ b/frontend/src/metabase/reference/databases/TableQuestions.jsx
@@ -10,13 +10,13 @@ import * as Urls from "metabase/lib/urls";
 
 import S from "metabase/components/List.css";
 
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
-import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
+import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx b/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx
index 099050c1e89b14cfe6c6c88470d24278a8e2b0d4..89658b90a1a22726fa867bf133787892871f7629 100644
--- a/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx
+++ b/frontend/src/metabase/reference/databases/TableQuestionsContainer.jsx
@@ -3,10 +3,10 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import TableSidebar from "./TableSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
+import TableSidebar from "./TableSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
 
-import TableQuestions from "metabase/reference/databases/TableQuestions.jsx";
+import TableQuestions from "metabase/reference/databases/TableQuestions";
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
 
diff --git a/frontend/src/metabase/reference/guide/BaseSidebar.jsx b/frontend/src/metabase/reference/guide/BaseSidebar.jsx
index 9a1d8fb9a707bb39ee50d3431acb7828b10464f7..cea6f06d1b5048fca7586b008008db60c81a8c97 100644
--- a/frontend/src/metabase/reference/guide/BaseSidebar.jsx
+++ b/frontend/src/metabase/reference/guide/BaseSidebar.jsx
@@ -3,8 +3,8 @@ import React from "react";
 import PropTypes from "prop-types";
 import S from "metabase/components/Sidebar.css";
 import { t } from "ttag";
-import Breadcrumbs from "metabase/components/Breadcrumbs.jsx";
-import SidebarItem from "metabase/components/SidebarItem.jsx";
+import Breadcrumbs from "metabase/components/Breadcrumbs";
+import SidebarItem from "metabase/components/SidebarItem";
 
 import cx from "classnames";
 import pure from "recompose/pure";
diff --git a/frontend/src/metabase/reference/guide/GettingStartedGuide.jsx b/frontend/src/metabase/reference/guide/GettingStartedGuide.jsx
index 659eaf1937e1624ba7ca4e3b16c8178a6e750b30..5cdc54c64070182658c8117033be5c5ae44243a1 100644
--- a/frontend/src/metabase/reference/guide/GettingStartedGuide.jsx
+++ b/frontend/src/metabase/reference/guide/GettingStartedGuide.jsx
@@ -6,10 +6,10 @@ import { connect } from "react-redux";
 import { t, jt } from "ttag";
 import cx from "classnames";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import GuideHeader from "metabase/reference/components/GuideHeader.jsx";
-import GuideDetail from "metabase/reference/components/GuideDetail.jsx";
+import GuideHeader from "metabase/reference/components/GuideHeader";
+import GuideDetail from "metabase/reference/components/GuideDetail";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/guide/GettingStartedGuideContainer.jsx b/frontend/src/metabase/reference/guide/GettingStartedGuideContainer.jsx
index 7bcc473e1e545b3af3a207423ec7a3d46832eb93..da2ed33d2f1044bf6a1aae17aa79ae5c6206e627 100644
--- a/frontend/src/metabase/reference/guide/GettingStartedGuideContainer.jsx
+++ b/frontend/src/metabase/reference/guide/GettingStartedGuideContainer.jsx
@@ -3,8 +3,8 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import GettingStartedGuide from "metabase/reference/guide/GettingStartedGuide.jsx";
-import GettingStartedGuideEditForm from "metabase/reference/guide/GettingStartedGuideEditForm.jsx";
+import GettingStartedGuide from "metabase/reference/guide/GettingStartedGuide";
+import GettingStartedGuideEditForm from "metabase/reference/guide/GettingStartedGuideEditForm";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/guide/GettingStartedGuideEditForm.jsx b/frontend/src/metabase/reference/guide/GettingStartedGuideEditForm.jsx
index 8f5d6fcff43dc28400d253023026d3b0e119393a..0dc8e1e0fb737bd74f1492725cb159bdd300b341 100644
--- a/frontend/src/metabase/reference/guide/GettingStartedGuideEditForm.jsx
+++ b/frontend/src/metabase/reference/guide/GettingStartedGuideEditForm.jsx
@@ -6,13 +6,13 @@ import { reduxForm } from "redux-form";
 import { t } from "ttag";
 import cx from "classnames";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
-import CreateDashboardModal from "metabase/components/CreateDashboardModal.jsx";
-import Modal from "metabase/components/Modal.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import CreateDashboardModal from "metabase/components/CreateDashboardModal";
+import Modal from "metabase/components/Modal";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import GuideEditSection from "metabase/reference/components/GuideEditSection.jsx";
-import GuideDetailEditor from "metabase/reference/components/GuideDetailEditor.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import GuideEditSection from "metabase/reference/components/GuideEditSection";
+import GuideDetailEditor from "metabase/reference/components/GuideDetailEditor";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/metrics/MetricDetail.jsx b/frontend/src/metabase/reference/metrics/MetricDetail.jsx
index 6a979528e2686cb61d1d4250d7c7718333ebdcb8..4d10e24b5007803ac8794f52a66c4936427939d7 100644
--- a/frontend/src/metabase/reference/metrics/MetricDetail.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricDetail.jsx
@@ -5,14 +5,14 @@ import { connect } from "react-redux";
 import { reduxForm } from "redux-form";
 import { push } from "react-router-redux";
 import { t } from "ttag";
-import List from "metabase/components/List.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
-import Detail from "metabase/reference/components/Detail.jsx";
-import FieldsToGroupBy from "metabase/reference/components/FieldsToGroupBy.jsx";
-import Formula from "metabase/reference/components/Formula.jsx";
-import MetricImportantFieldsDetail from "metabase/reference/components/MetricImportantFieldsDetail.jsx";
+import List from "metabase/components/List";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
+import Detail from "metabase/reference/components/Detail";
+import FieldsToGroupBy from "metabase/reference/components/FieldsToGroupBy";
+import Formula from "metabase/reference/components/Formula";
+import MetricImportantFieldsDetail from "metabase/reference/components/MetricImportantFieldsDetail";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/metrics/MetricDetailContainer.jsx b/frontend/src/metabase/reference/metrics/MetricDetailContainer.jsx
index 4b89cabf30a72a22671e4ba16ebcd5da243b26d9..d2aa2338c49ee66538f27e26df929d017bff76ec 100644
--- a/frontend/src/metabase/reference/metrics/MetricDetailContainer.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricDetailContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import MetricSidebar from "./MetricSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import MetricDetail from "metabase/reference/metrics/MetricDetail.jsx";
+import MetricSidebar from "./MetricSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import MetricDetail from "metabase/reference/metrics/MetricDetail";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/metrics/MetricList.jsx b/frontend/src/metabase/reference/metrics/MetricList.jsx
index 1eccd30a6c98c9ffb8f17248708e9c73b041c4aa..12a9e27634ffd4bdc8ce3fa131f60380b4b82c33 100644
--- a/frontend/src/metabase/reference/metrics/MetricList.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricList.jsx
@@ -7,13 +7,13 @@ import { isQueryable } from "metabase/lib/table";
 
 import S from "metabase/components/List.css";
 
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
-import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
+import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 import { getMetrics, getError, getLoading } from "../selectors";
 
diff --git a/frontend/src/metabase/reference/metrics/MetricListContainer.jsx b/frontend/src/metabase/reference/metrics/MetricListContainer.jsx
index 8e6099298926b2518620d4c6224deee4071651da..c1501280448996ec5896aed2fde4eed977f85f9e 100644
--- a/frontend/src/metabase/reference/metrics/MetricListContainer.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricListContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import BaseSidebar from "metabase/reference/guide/BaseSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import MetricList from "metabase/reference/metrics/MetricList.jsx";
+import BaseSidebar from "metabase/reference/guide/BaseSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import MetricList from "metabase/reference/metrics/MetricList";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/metrics/MetricQuestions.jsx b/frontend/src/metabase/reference/metrics/MetricQuestions.jsx
index 9bdf0446f83f076719edd5f98a460bd98a23042e..7df2de9547cebca9dd81ac563c03b9d374b41377 100644
--- a/frontend/src/metabase/reference/metrics/MetricQuestions.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricQuestions.jsx
@@ -10,13 +10,13 @@ import * as Urls from "metabase/lib/urls";
 
 import S from "metabase/components/List.css";
 
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
-import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
+import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/metrics/MetricQuestionsContainer.jsx b/frontend/src/metabase/reference/metrics/MetricQuestionsContainer.jsx
index 3701953aeb1e978bf0d8e4f904a44f26bb83f6f8..66a253964be7181b38ea28a95a2be246e4d0159c 100644
--- a/frontend/src/metabase/reference/metrics/MetricQuestionsContainer.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricQuestionsContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import MetricSidebar from "./MetricSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import MetricQuestions from "metabase/reference/metrics/MetricQuestions.jsx";
+import MetricSidebar from "./MetricSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import MetricQuestions from "metabase/reference/metrics/MetricQuestions";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/metrics/MetricRevisions.jsx b/frontend/src/metabase/reference/metrics/MetricRevisions.jsx
index dccb369c2be5d322081cac63338861405f50741a..dc9e411fd6f6d045a021ec52fee7523e3e7240db 100644
--- a/frontend/src/metabase/reference/metrics/MetricRevisions.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricRevisions.jsx
@@ -20,10 +20,10 @@ import {
   getError,
 } from "../selectors";
 
-import Revision from "metabase/admin/datamodel/components/revisions/Revision.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
-import EmptyState from "metabase/components/EmptyState.jsx";
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import Revision from "metabase/admin/datamodel/components/revisions/Revision";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import EmptyState from "metabase/components/EmptyState";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 const emptyStateData = {
   message: t`There are no revisions for this metric`,
diff --git a/frontend/src/metabase/reference/metrics/MetricRevisionsContainer.jsx b/frontend/src/metabase/reference/metrics/MetricRevisionsContainer.jsx
index a48a83c18ba1da32ef41cc738a3d2c5678c43247..c7eb95606bf8d6a6b7dc911969a0d36bee9fefd2 100644
--- a/frontend/src/metabase/reference/metrics/MetricRevisionsContainer.jsx
+++ b/frontend/src/metabase/reference/metrics/MetricRevisionsContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import MetricSidebar from "./MetricSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import MetricRevisions from "metabase/reference/metrics/MetricRevisions.jsx";
+import MetricSidebar from "./MetricSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import MetricRevisions from "metabase/reference/metrics/MetricRevisions";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentDetail.jsx b/frontend/src/metabase/reference/segments/SegmentDetail.jsx
index 44a0c3db0f10884ff81e206c2c672468e1ba5a31..ba965a9ed2e73ae446c3cb3439f793c5923badcb 100644
--- a/frontend/src/metabase/reference/segments/SegmentDetail.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentDetail.jsx
@@ -4,14 +4,14 @@ import PropTypes from "prop-types";
 import { connect } from "react-redux";
 import { reduxForm } from "redux-form";
 import { t } from "ttag";
-import List from "metabase/components/List.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import List from "metabase/components/List";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
-import Detail from "metabase/reference/components/Detail.jsx";
-import UsefulQuestions from "metabase/reference/components/UsefulQuestions.jsx";
-import Formula from "metabase/reference/components/Formula.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
+import Detail from "metabase/reference/components/Detail";
+import UsefulQuestions from "metabase/reference/components/UsefulQuestions";
+import Formula from "metabase/reference/components/Formula";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx b/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx
index a1715aacd753924e06f2b06994e427d8ae7a0de1..17a950520682dea06aef7b28af38b148f0ddd95a 100644
--- a/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentDetailContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import SegmentSidebar from "./SegmentSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import SegmentDetail from "metabase/reference/segments/SegmentDetail.jsx";
+import SegmentSidebar from "./SegmentSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import SegmentDetail from "metabase/reference/segments/SegmentDetail";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx b/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx
index 9b572da9134dca2a555ae49e28e9f6d47164f580..5f1f37c64b3032bd32a648cacfbafc5b2b771e0d 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldDetail.jsx
@@ -6,14 +6,14 @@ import { reduxForm } from "redux-form";
 import { t } from "ttag";
 import S from "metabase/reference/Reference.css";
 
-import List from "metabase/components/List.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import List from "metabase/components/List";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
-import Detail from "metabase/reference/components/Detail.jsx";
-import FieldTypeDetail from "metabase/reference/components/FieldTypeDetail.jsx";
-import UsefulQuestions from "metabase/reference/components/UsefulQuestions.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
+import Detail from "metabase/reference/components/Detail";
+import FieldTypeDetail from "metabase/reference/components/FieldTypeDetail";
+import UsefulQuestions from "metabase/reference/components/UsefulQuestions";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx b/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx
index 65fefd31738571683dcf01a9bd681b6d29316584..65fd80979fd4607dee5ab8a5abb9c17b76b6bdc3 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldDetailContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import SegmentFieldSidebar from "./SegmentFieldSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import SegmentFieldDetail from "metabase/reference/segments/SegmentFieldDetail.jsx";
+import SegmentFieldSidebar from "./SegmentFieldSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import SegmentFieldDetail from "metabase/reference/segments/SegmentFieldDetail";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldList.jsx b/frontend/src/metabase/reference/segments/SegmentFieldList.jsx
index fe292efd564bed51145939d6f998fba7b89a75b7..09d3f9ff78959d327c4180f336ba277abc4be6a0 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldList.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldList.jsx
@@ -8,13 +8,13 @@ import S from "metabase/components/List.css";
 import R from "metabase/reference/Reference.css";
 import F from "metabase/reference/components/Field.css";
 
-import Field from "metabase/reference/components/Field.jsx";
-import List from "metabase/components/List.jsx";
-import EmptyState from "metabase/components/EmptyState.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import Field from "metabase/reference/components/Field";
+import List from "metabase/components/List";
+import EmptyState from "metabase/components/EmptyState";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import EditHeader from "metabase/reference/components/EditHeader.jsx";
-import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader.jsx";
+import EditHeader from "metabase/reference/components/EditHeader";
+import EditableReferenceHeader from "metabase/reference/components/EditableReferenceHeader";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx b/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx
index 8326c4fd2e683ab3fa6b648da9b1eb2b9a46899e..688aa6fda2a4ab6e8b4d0ebbdf423fa9528b1ca3 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldListContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import SegmentSidebar from "./SegmentSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import SegmentFieldList from "metabase/reference/segments/SegmentFieldList.jsx";
+import SegmentSidebar from "./SegmentSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import SegmentFieldList from "metabase/reference/segments/SegmentFieldList";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentFieldSidebar.jsx b/frontend/src/metabase/reference/segments/SegmentFieldSidebar.jsx
index 2993382ce1f0b45528441e9c6864b574e657f7c2..8bb1779a568d57a2d40a0f59bb9ce1147ebcbda6 100644
--- a/frontend/src/metabase/reference/segments/SegmentFieldSidebar.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentFieldSidebar.jsx
@@ -3,8 +3,8 @@ import React from "react";
 import PropTypes from "prop-types";
 import S from "metabase/components/Sidebar.css";
 import { t } from "ttag";
-import Breadcrumbs from "metabase/components/Breadcrumbs.jsx";
-import SidebarItem from "metabase/components/SidebarItem.jsx";
+import Breadcrumbs from "metabase/components/Breadcrumbs";
+import SidebarItem from "metabase/components/SidebarItem";
 
 import cx from "classnames";
 import pure from "recompose/pure";
diff --git a/frontend/src/metabase/reference/segments/SegmentList.jsx b/frontend/src/metabase/reference/segments/SegmentList.jsx
index 3c2708ae7f010f05f02538a20f795e83a19c15e0..4ae815e7067a99b80ec1051852e73519cfee0639 100644
--- a/frontend/src/metabase/reference/segments/SegmentList.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentList.jsx
@@ -8,13 +8,13 @@ import MetabaseSettings from "metabase/lib/settings";
 
 import S from "metabase/components/List.css";
 
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
-import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
+import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 import { getSegments, getError, getLoading } from "../selectors";
 
diff --git a/frontend/src/metabase/reference/segments/SegmentListContainer.jsx b/frontend/src/metabase/reference/segments/SegmentListContainer.jsx
index d2e66af545e26c3062877a63ff7b59c57faba0be..947133b2f09fd33450292246d79542c87e1d7a72 100644
--- a/frontend/src/metabase/reference/segments/SegmentListContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentListContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import BaseSidebar from "metabase/reference/guide/BaseSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import SegmentList from "metabase/reference/segments/SegmentList.jsx";
+import BaseSidebar from "metabase/reference/guide/BaseSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import SegmentList from "metabase/reference/segments/SegmentList";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentQuestions.jsx b/frontend/src/metabase/reference/segments/SegmentQuestions.jsx
index 34f38de370995f383c458612c028e13e88a3b617..366736a787d3d6af6145edba765366507d57285f 100644
--- a/frontend/src/metabase/reference/segments/SegmentQuestions.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentQuestions.jsx
@@ -10,13 +10,13 @@ import * as Urls from "metabase/lib/urls";
 
 import S from "metabase/components/List.css";
 
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
-import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
+import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
 
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
 
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 import { getQuestionUrl } from "../utils";
 
diff --git a/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx b/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx
index 97fd99500777a4dc9d36750cda06d5e2f31ebab6..7f28b0a5e8f5aa0da82978c4d9017f957bb9f6cd 100644
--- a/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentQuestionsContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import SegmentSidebar from "./SegmentSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import SegmentQuestions from "metabase/reference/segments/SegmentQuestions.jsx";
+import SegmentSidebar from "./SegmentSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import SegmentQuestions from "metabase/reference/segments/SegmentQuestions";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/segments/SegmentRevisions.jsx b/frontend/src/metabase/reference/segments/SegmentRevisions.jsx
index b7c127894696d3c2b552b7fffd0f50eb2173182e..39740657276db422f46b6baf3b0002614e33212a 100644
--- a/frontend/src/metabase/reference/segments/SegmentRevisions.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentRevisions.jsx
@@ -20,10 +20,10 @@ import {
   getError,
 } from "../selectors";
 
-import Revision from "metabase/admin/datamodel/components/revisions/Revision.jsx";
-import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
-import EmptyState from "metabase/components/EmptyState.jsx";
-import ReferenceHeader from "../components/ReferenceHeader.jsx";
+import Revision from "metabase/admin/datamodel/components/revisions/Revision";
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
+import EmptyState from "metabase/components/EmptyState";
+import ReferenceHeader from "../components/ReferenceHeader";
 
 const emptyStateData = {
   message: t`There are no revisions for this segment`,
diff --git a/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx b/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx
index ccff3d570e1ffced506b1662a82412b5b7e2dc1e..6a72e0cfd3bc490b1846557b00590888ca8939f8 100644
--- a/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx
+++ b/frontend/src/metabase/reference/segments/SegmentRevisionsContainer.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { connect } from "react-redux";
 
-import SegmentSidebar from "./SegmentSidebar.jsx";
-import SidebarLayout from "metabase/components/SidebarLayout.jsx";
-import SegmentRevisions from "metabase/reference/segments/SegmentRevisions.jsx";
+import SegmentSidebar from "./SegmentSidebar";
+import SidebarLayout from "metabase/components/SidebarLayout";
+import SegmentRevisions from "metabase/reference/segments/SegmentRevisions";
 
 import * as metadataActions from "metabase/redux/metadata";
 import * as actions from "metabase/reference/reference";
diff --git a/frontend/src/metabase/reference/utils.js b/frontend/src/metabase/reference/utils.js
index 939c0bfb7e722cafb2151cc33bce56e9c5968baa..18170d2852ef31f27ee36af19aca42a83e43e032 100644
--- a/frontend/src/metabase/reference/utils.js
+++ b/frontend/src/metabase/reference/utils.js
@@ -71,7 +71,7 @@ export const getQuestion = ({
   // http://ramdajs.com/0.21.0/index.html
   const question = chain(newQuestion)
     .updateIn(["dataset_query", "query", "aggregation"], aggregation =>
-      getCount ? ["count"] : aggregation,
+      getCount ? [["count"]] : aggregation,
     )
     .updateIn(["display"], display => visualization || display)
     .updateIn(["dataset_query", "query", "breakout"], oldBreakout => {
@@ -89,7 +89,7 @@ export const getQuestion = ({
     return assocIn(
       question,
       ["dataset_query", "query", "aggregation"],
-      ["metric", metricId],
+      [["metric", metricId]],
     );
   }
 
@@ -97,7 +97,7 @@ export const getQuestion = ({
     return assocIn(
       question,
       ["dataset_query", "query", "filter"],
-      ["and", ["segment", segmentId]],
+      ["segment", segmentId],
     );
   }
 
diff --git a/frontend/src/metabase/routes-embed.jsx b/frontend/src/metabase/routes-embed.jsx
index 0f2628b0a37db4d9055a0c863613f6f4f5136b76..1b2a03869e8229a09c3da138305625885730d5a7 100644
--- a/frontend/src/metabase/routes-embed.jsx
+++ b/frontend/src/metabase/routes-embed.jsx
@@ -6,9 +6,9 @@ import { Route } from "react-router";
 
 import PublicNotFound from "metabase/public/components/PublicNotFound";
 
-import PublicApp from "metabase/public/containers/PublicApp.jsx";
-import PublicQuestion from "metabase/public/containers/PublicQuestion.jsx";
-import PublicDashboard from "metabase/public/containers/PublicDashboard.jsx";
+import PublicApp from "metabase/public/containers/PublicApp";
+import PublicQuestion from "metabase/public/containers/PublicQuestion";
+import PublicDashboard from "metabase/public/containers/PublicDashboard";
 
 export const getRoutes = store => (
   <Route>
diff --git a/frontend/src/metabase/routes-public.jsx b/frontend/src/metabase/routes-public.jsx
index 194ed7c61a1fb45f73d9826be55dc1ead91cf1e3..4cee214b38076f4bddd08361459c465a91acc40a 100644
--- a/frontend/src/metabase/routes-public.jsx
+++ b/frontend/src/metabase/routes-public.jsx
@@ -6,9 +6,9 @@ import { Route } from "react-router";
 
 import PublicNotFound from "metabase/public/components/PublicNotFound";
 
-import PublicApp from "metabase/public/containers/PublicApp.jsx";
-import PublicQuestion from "metabase/public/containers/PublicQuestion.jsx";
-import PublicDashboard from "metabase/public/containers/PublicDashboard.jsx";
+import PublicApp from "metabase/public/containers/PublicApp";
+import PublicQuestion from "metabase/public/containers/PublicQuestion";
+import PublicDashboard from "metabase/public/containers/PublicDashboard";
 
 export const getRoutes = store => (
   <Route>
diff --git a/frontend/src/metabase/routes.jsx b/frontend/src/metabase/routes.jsx
index b48286c7dcf43ea67021096a37224280867a51cc..3f7ca90835a5ae7d8583fc4d684ebb9e303a566f 100644
--- a/frontend/src/metabase/routes.jsx
+++ b/frontend/src/metabase/routes.jsx
@@ -17,11 +17,11 @@ import HomepageApp from "metabase/home/containers/HomepageApp";
 
 // auth containers
 import AuthApp from "metabase/auth/AuthApp";
-import ForgotPasswordApp from "metabase/auth/containers/ForgotPasswordApp.jsx";
-import LoginApp from "metabase/auth/containers/LoginApp.jsx";
-import LogoutApp from "metabase/auth/containers/LogoutApp.jsx";
-import PasswordResetApp from "metabase/auth/containers/PasswordResetApp.jsx";
-import GoogleNoAccount from "metabase/auth/components/GoogleNoAccount.jsx";
+import ForgotPasswordApp from "metabase/auth/containers/ForgotPasswordApp";
+import LoginApp from "metabase/auth/containers/LoginApp";
+import LogoutApp from "metabase/auth/containers/LogoutApp";
+import PasswordResetApp from "metabase/auth/containers/PasswordResetApp";
+import GoogleNoAccount from "metabase/auth/components/GoogleNoAccount";
 
 /* Dashboards */
 import DashboardApp from "metabase/dashboard/containers/DashboardApp";
@@ -34,19 +34,19 @@ import {
   TableBrowser,
 } from "metabase/components/BrowseApp";
 
-import QueryBuilder from "metabase/query_builder/containers/QueryBuilder.jsx";
+import QueryBuilder from "metabase/query_builder/containers/QueryBuilder";
 
-import CollectionEdit from "metabase/collections/containers/CollectionEdit.jsx";
-import CollectionCreate from "metabase/collections/containers/CollectionCreate.jsx";
+import CollectionEdit from "metabase/collections/containers/CollectionEdit";
+import CollectionCreate from "metabase/collections/containers/CollectionCreate";
 import ArchiveCollectionModal from "metabase/components/ArchiveCollectionModal";
 import CollectionPermissionsModal from "metabase/admin/permissions/containers/CollectionPermissionsModal";
 import UserCollectionList from "metabase/containers/UserCollectionList";
 
-import PulseEditApp from "metabase/pulse/containers/PulseEditApp.jsx";
-import SetupApp from "metabase/setup/containers/SetupApp.jsx";
-import PostSetupApp from "metabase/setup/containers/PostSetupApp.jsx";
-import UserSettingsApp from "metabase/user/containers/UserSettingsApp.jsx";
-import EntityPage from "metabase/components/EntityPage.jsx";
+import PulseEditApp from "metabase/pulse/containers/PulseEditApp";
+import SetupApp from "metabase/setup/containers/SetupApp";
+import PostSetupApp from "metabase/setup/containers/PostSetupApp";
+import UserSettingsApp from "metabase/user/containers/UserSettingsApp";
+import EntityPage from "metabase/components/EntityPage";
 // new question
 import NewQueryOptions from "metabase/new_query/containers/NewQueryOptions";
 
@@ -55,32 +55,32 @@ import CreateDashboardModal from "metabase/components/CreateDashboardModal";
 import { NotFound, Unauthorized } from "metabase/containers/ErrorPages";
 
 // Reference Guide
-import GettingStartedGuideContainer from "metabase/reference/guide/GettingStartedGuideContainer.jsx";
+import GettingStartedGuideContainer from "metabase/reference/guide/GettingStartedGuideContainer";
 // Reference Metrics
-import MetricListContainer from "metabase/reference/metrics/MetricListContainer.jsx";
-import MetricDetailContainer from "metabase/reference/metrics/MetricDetailContainer.jsx";
-import MetricQuestionsContainer from "metabase/reference/metrics/MetricQuestionsContainer.jsx";
-import MetricRevisionsContainer from "metabase/reference/metrics/MetricRevisionsContainer.jsx";
+import MetricListContainer from "metabase/reference/metrics/MetricListContainer";
+import MetricDetailContainer from "metabase/reference/metrics/MetricDetailContainer";
+import MetricQuestionsContainer from "metabase/reference/metrics/MetricQuestionsContainer";
+import MetricRevisionsContainer from "metabase/reference/metrics/MetricRevisionsContainer";
 // Reference Segments
-import SegmentListContainer from "metabase/reference/segments/SegmentListContainer.jsx";
-import SegmentDetailContainer from "metabase/reference/segments/SegmentDetailContainer.jsx";
-import SegmentQuestionsContainer from "metabase/reference/segments/SegmentQuestionsContainer.jsx";
-import SegmentRevisionsContainer from "metabase/reference/segments/SegmentRevisionsContainer.jsx";
-import SegmentFieldListContainer from "metabase/reference/segments/SegmentFieldListContainer.jsx";
-import SegmentFieldDetailContainer from "metabase/reference/segments/SegmentFieldDetailContainer.jsx";
+import SegmentListContainer from "metabase/reference/segments/SegmentListContainer";
+import SegmentDetailContainer from "metabase/reference/segments/SegmentDetailContainer";
+import SegmentQuestionsContainer from "metabase/reference/segments/SegmentQuestionsContainer";
+import SegmentRevisionsContainer from "metabase/reference/segments/SegmentRevisionsContainer";
+import SegmentFieldListContainer from "metabase/reference/segments/SegmentFieldListContainer";
+import SegmentFieldDetailContainer from "metabase/reference/segments/SegmentFieldDetailContainer";
 // Reference Databases
-import DatabaseListContainer from "metabase/reference/databases/DatabaseListContainer.jsx";
-import DatabaseDetailContainer from "metabase/reference/databases/DatabaseDetailContainer.jsx";
-import TableListContainer from "metabase/reference/databases/TableListContainer.jsx";
-import TableDetailContainer from "metabase/reference/databases/TableDetailContainer.jsx";
-import TableQuestionsContainer from "metabase/reference/databases/TableQuestionsContainer.jsx";
-import FieldListContainer from "metabase/reference/databases/FieldListContainer.jsx";
-import FieldDetailContainer from "metabase/reference/databases/FieldDetailContainer.jsx";
+import DatabaseListContainer from "metabase/reference/databases/DatabaseListContainer";
+import DatabaseDetailContainer from "metabase/reference/databases/DatabaseDetailContainer";
+import TableListContainer from "metabase/reference/databases/TableListContainer";
+import TableDetailContainer from "metabase/reference/databases/TableDetailContainer";
+import TableQuestionsContainer from "metabase/reference/databases/TableQuestionsContainer";
+import FieldListContainer from "metabase/reference/databases/FieldListContainer";
+import FieldDetailContainer from "metabase/reference/databases/FieldDetailContainer";
 
 import getAdminRoutes from "metabase/admin/routes";
 
-import PublicQuestion from "metabase/public/containers/PublicQuestion.jsx";
-import PublicDashboard from "metabase/public/containers/PublicDashboard.jsx";
+import PublicQuestion from "metabase/public/containers/PublicQuestion";
+import PublicDashboard from "metabase/public/containers/PublicDashboard";
 import DashboardHistoryModal from "metabase/dashboard/components/DashboardHistoryModal";
 import DashboardMoveModal from "metabase/dashboard/components/DashboardMoveModal";
 import DashboardCopyModal from "metabase/dashboard/components/DashboardCopyModal";
@@ -89,7 +89,7 @@ import { ModalRoute } from "metabase/hoc/ModalRoute";
 import CollectionLanding from "metabase/components/CollectionLanding";
 import Overworld from "metabase/containers/Overworld";
 
-import ArchiveApp from "metabase/home/containers/ArchiveApp.jsx";
+import ArchiveApp from "metabase/home/containers/ArchiveApp";
 import SearchApp from "metabase/home/containers/SearchApp";
 
 const MetabaseIsSetup = UserAuthWrapper({
diff --git a/frontend/src/metabase/setup/components/CollapsedStep.jsx b/frontend/src/metabase/setup/components/CollapsedStep.jsx
index bf48e5f91c3961db2335b0b3da8eaac2ccc583a5..5095e489e3f6b9a122d3b29c60fd9b254c0c2c9a 100644
--- a/frontend/src/metabase/setup/components/CollapsedStep.jsx
+++ b/frontend/src/metabase/setup/components/CollapsedStep.jsx
@@ -2,7 +2,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 export default class CollapsedStep extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/setup/components/DatabaseConnectionStep.jsx b/frontend/src/metabase/setup/components/DatabaseConnectionStep.jsx
index 78ffdd009fd70260c097e88bfeb3924ae3532c34..9e5cf46f71c8584a43ba41fdc857d1eef79bf7b4 100644
--- a/frontend/src/metabase/setup/components/DatabaseConnectionStep.jsx
+++ b/frontend/src/metabase/setup/components/DatabaseConnectionStep.jsx
@@ -2,11 +2,11 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import StepTitle from "./StepTitle.jsx";
-import CollapsedStep from "./CollapsedStep.jsx";
+import StepTitle from "./StepTitle";
+import CollapsedStep from "./CollapsedStep";
 
-import DatabaseDetailsForm from "metabase/components/DatabaseDetailsForm.jsx";
-import FormField from "metabase/components/form/FormField.jsx";
+import DatabaseDetailsForm from "metabase/components/DatabaseDetailsForm";
+import FormField from "metabase/components/form/FormField";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import MetabaseSettings from "metabase/lib/settings";
 
diff --git a/frontend/src/metabase/setup/components/DatabaseSchedulingStep.jsx b/frontend/src/metabase/setup/components/DatabaseSchedulingStep.jsx
index 5721762af41e53f1b08a232bf288765d1e3c74cf..a75dca29f8ca1adfb66bd672ee8297976e2f12aa 100644
--- a/frontend/src/metabase/setup/components/DatabaseSchedulingStep.jsx
+++ b/frontend/src/metabase/setup/components/DatabaseSchedulingStep.jsx
@@ -2,8 +2,8 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import StepTitle from "./StepTitle.jsx";
-import CollapsedStep from "./CollapsedStep.jsx";
+import StepTitle from "./StepTitle";
+import CollapsedStep from "./CollapsedStep";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
 
diff --git a/frontend/src/metabase/setup/components/PreferencesStep.jsx b/frontend/src/metabase/setup/components/PreferencesStep.jsx
index 6a0664c134f32bdb100f9e3d0b38c66c43a00cce..4e099ab79f8363080988e2d9dcf38fd68846560f 100644
--- a/frontend/src/metabase/setup/components/PreferencesStep.jsx
+++ b/frontend/src/metabase/setup/components/PreferencesStep.jsx
@@ -4,10 +4,10 @@ import PropTypes from "prop-types";
 import { t, jt } from "ttag";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import MetabaseSettings from "metabase/lib/settings";
-import Toggle from "metabase/components/Toggle.jsx";
+import Toggle from "metabase/components/Toggle";
 
-import StepTitle from "./StepTitle.jsx";
-import CollapsedStep from "./CollapsedStep.jsx";
+import StepTitle from "./StepTitle";
+import CollapsedStep from "./CollapsedStep";
 
 export default class PreferencesStep extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/setup/components/Setup.jsx b/frontend/src/metabase/setup/components/Setup.jsx
index a01b90fdfc4f2562e5b62eff2ec2f7169eb9e9fe..4e4c8777c3983ee8477197574c0af82bbdc8ea56 100644
--- a/frontend/src/metabase/setup/components/Setup.jsx
+++ b/frontend/src/metabase/setup/components/Setup.jsx
@@ -4,14 +4,14 @@ import ReactDOM from "react-dom";
 import PropTypes from "prop-types";
 import { Link } from "react-router";
 import { t } from "ttag";
-import LogoIcon from "metabase/components/LogoIcon.jsx";
-import NewsletterForm from "metabase/components/NewsletterForm.jsx";
+import LogoIcon from "metabase/components/LogoIcon";
+import NewsletterForm from "metabase/components/NewsletterForm";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import MetabaseSettings from "metabase/lib/settings";
 
-import UserStep from "./UserStep.jsx";
-import DatabaseConnectionStep from "./DatabaseConnectionStep.jsx";
-import PreferencesStep from "./PreferencesStep.jsx";
+import UserStep from "./UserStep";
+import DatabaseConnectionStep from "./DatabaseConnectionStep";
+import PreferencesStep from "./PreferencesStep";
 import DatabaseSchedulingStep from "metabase/setup/components/DatabaseSchedulingStep";
 
 const WELCOME_STEP_NUMBER = 0;
diff --git a/frontend/src/metabase/setup/components/StepTitle.jsx b/frontend/src/metabase/setup/components/StepTitle.jsx
index a361db6d2e7d054ad6008e5232deb66d37f51c1e..0e104af6576795ecd9e9aeae3f8a716a4d442232 100644
--- a/frontend/src/metabase/setup/components/StepTitle.jsx
+++ b/frontend/src/metabase/setup/components/StepTitle.jsx
@@ -1,7 +1,7 @@
 /* eslint "react/prop-types": "warn" */
 import React, { Component } from "react";
 import PropTypes from "prop-types";
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 export default class StepTitle extends Component {
   static propTypes = {
diff --git a/frontend/src/metabase/setup/components/UserStep.jsx b/frontend/src/metabase/setup/components/UserStep.jsx
index e18814739112c2b69985aafa5565f405a247c092..95a033d63c80b91738350ed7ba26a930e27d520c 100644
--- a/frontend/src/metabase/setup/components/UserStep.jsx
+++ b/frontend/src/metabase/setup/components/UserStep.jsx
@@ -3,15 +3,15 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { Box, Flex } from "grid-styled";
 import { t } from "ttag";
-import FormField from "metabase/components/form/FormField.jsx";
-import FormLabel from "metabase/components/form/FormLabel.jsx";
-import FormMessage from "metabase/components/form/FormMessage.jsx";
+import FormField from "metabase/components/form/FormField";
+import FormLabel from "metabase/components/form/FormLabel";
+import FormMessage from "metabase/components/form/FormMessage";
 import MetabaseAnalytics from "metabase/lib/analytics";
 import MetabaseSettings from "metabase/lib/settings";
 import MetabaseUtils from "metabase/lib/utils";
 
-import StepTitle from "./StepTitle.jsx";
-import CollapsedStep from "./CollapsedStep.jsx";
+import StepTitle from "./StepTitle";
+import CollapsedStep from "./CollapsedStep";
 
 import _ from "underscore";
 import cx from "classnames";
diff --git a/frontend/src/metabase/setup/containers/SetupApp.jsx b/frontend/src/metabase/setup/containers/SetupApp.jsx
index cb9130754985dc0d5c411145122eb6419647f4bb..9a006f418538d8ede085f8bc7379aac2919f3955 100644
--- a/frontend/src/metabase/setup/containers/SetupApp.jsx
+++ b/frontend/src/metabase/setup/containers/SetupApp.jsx
@@ -3,7 +3,7 @@ import React, { Component } from "react";
 import { connect } from "react-redux";
 import fitViewport from "metabase/hoc/FitViewPort";
 
-import Setup from "../components/Setup.jsx";
+import Setup from "../components/Setup";
 
 import { setupSelectors } from "../selectors";
 import {
diff --git a/frontend/src/metabase/user/components/SetUserPassword.jsx b/frontend/src/metabase/user/components/SetUserPassword.jsx
index 26efd37211f4d070a95abe77baba6676d429c943..61015f1cddd48387d4eed70ea29a5b95277fd659 100644
--- a/frontend/src/metabase/user/components/SetUserPassword.jsx
+++ b/frontend/src/metabase/user/components/SetUserPassword.jsx
@@ -3,9 +3,9 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import ReactDOM from "react-dom";
 import { t } from "ttag";
-import FormField from "metabase/components/form/FormField.jsx";
-import FormLabel from "metabase/components/form/FormLabel.jsx";
-import FormMessage from "metabase/components/form/FormMessage.jsx";
+import FormField from "metabase/components/form/FormField";
+import FormLabel from "metabase/components/form/FormLabel";
+import FormMessage from "metabase/components/form/FormMessage";
 
 import MetabaseUtils from "metabase/lib/utils";
 import MetabaseSettings from "metabase/lib/settings";
diff --git a/frontend/src/metabase/user/containers/UserSettingsApp.jsx b/frontend/src/metabase/user/containers/UserSettingsApp.jsx
index d182f6590b7eea357e0461529b9b9767688708fd..f8eb88df5692e15a246319478c85cc9c1cd14bc4 100644
--- a/frontend/src/metabase/user/containers/UserSettingsApp.jsx
+++ b/frontend/src/metabase/user/containers/UserSettingsApp.jsx
@@ -2,7 +2,7 @@
 import React, { Component } from "react";
 import { connect } from "react-redux";
 
-import UserSettings from "../components/UserSettings.jsx";
+import UserSettings from "../components/UserSettings";
 import { selectors } from "../selectors";
 
 import { setTab, updatePassword, updateUser } from "../actions";
diff --git a/frontend/src/metabase/visualizations/components/CardRenderer.jsx b/frontend/src/metabase/visualizations/components/CardRenderer.jsx
index 327267b7ac8d63819cdec767c9c40ebc266576a0..4a953ed831028b4538748a064622d327b638658a 100644
--- a/frontend/src/metabase/visualizations/components/CardRenderer.jsx
+++ b/frontend/src/metabase/visualizations/components/CardRenderer.jsx
@@ -4,7 +4,7 @@ import React, { Component } from "react";
 import PropTypes from "prop-types";
 import ReactDOM from "react-dom";
 
-import ExplicitSize from "metabase/components/ExplicitSize.jsx";
+import ExplicitSize from "metabase/components/ExplicitSize";
 
 import { isSameSeries } from "metabase/visualizations/lib/utils";
 
diff --git a/frontend/src/metabase/visualizations/components/ChartSettings.jsx b/frontend/src/metabase/visualizations/components/ChartSettings.jsx
index a40e60342285b16c41014d21c32e0da617c863e6..93ea6f187ac5d0e6d27180fa0b7286c276e50c5a 100644
--- a/frontend/src/metabase/visualizations/components/ChartSettings.jsx
+++ b/frontend/src/metabase/visualizations/components/ChartSettings.jsx
@@ -3,12 +3,12 @@ import cx from "classnames";
 import { assocIn } from "icepick";
 import _ from "underscore";
 import { t } from "ttag";
-import Warnings from "metabase/query_builder/components/Warnings.jsx";
+import Warnings from "metabase/query_builder/components/Warnings";
 
 import Button from "metabase/components/Button";
 import Radio from "metabase/components/Radio";
 
-import Visualization from "metabase/visualizations/components/Visualization.jsx";
+import Visualization from "metabase/visualizations/components/Visualization";
 import ChartSettingsWidget from "./ChartSettingsWidget";
 
 import { getSettingsWidgetsForSeries } from "metabase/visualizations/lib/settings/visualization";
diff --git a/frontend/src/metabase/visualizations/components/ChartTooltip.jsx b/frontend/src/metabase/visualizations/components/ChartTooltip.jsx
index de470e131f7d7162861f33fbc10eab3c6dcf01b0..bd754cc16f961fa3036992ec6eb0812b256a507b 100644
--- a/frontend/src/metabase/visualizations/components/ChartTooltip.jsx
+++ b/frontend/src/metabase/visualizations/components/ChartTooltip.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 
-import TooltipPopover from "metabase/components/TooltipPopover.jsx";
+import TooltipPopover from "metabase/components/TooltipPopover";
 
 import { getFriendlyName } from "metabase/visualizations/lib/utils";
 import { formatValue } from "metabase/lib/formatting";
diff --git a/frontend/src/metabase/visualizations/components/ChartWithLegend.jsx b/frontend/src/metabase/visualizations/components/ChartWithLegend.jsx
index 4b444a3f2af95eb07d67338a497f24d190b940d7..2a4e1328cebf907bd2892f56f61fea571574e655 100644
--- a/frontend/src/metabase/visualizations/components/ChartWithLegend.jsx
+++ b/frontend/src/metabase/visualizations/components/ChartWithLegend.jsx
@@ -1,10 +1,10 @@
 import React, { Component } from "react";
 import styles from "./ChartWithLegend.css";
 
-import LegendVertical from "./LegendVertical.jsx";
-import LegendHorizontal from "./LegendHorizontal.jsx";
+import LegendVertical from "./LegendVertical";
+import LegendHorizontal from "./LegendHorizontal";
 
-import ExplicitSize from "metabase/components/ExplicitSize.jsx";
+import ExplicitSize from "metabase/components/ExplicitSize";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx b/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
index 2d4148ae35b259e001f92b5662c4b14ec97013d2..fb0939b4d9edaa4f8fb3696d43fae4c6627f376c 100644
--- a/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
+++ b/frontend/src/metabase/visualizations/components/ChoroplethMap.jsx
@@ -2,7 +2,7 @@
 
 import React, { Component } from "react";
 import { t } from "ttag";
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
 
 import { isString } from "metabase/lib/schema_metadata";
 import { MinColumnsError } from "metabase/visualizations/lib/errors";
@@ -10,9 +10,9 @@ import MetabaseSettings from "metabase/lib/settings";
 
 import { formatValue } from "metabase/lib/formatting";
 
-import ChartWithLegend from "./ChartWithLegend.jsx";
-import LegacyChoropleth from "./LegacyChoropleth.jsx";
-import LeafletChoropleth from "./LeafletChoropleth.jsx";
+import ChartWithLegend from "./ChartWithLegend";
+import LegacyChoropleth from "./LegacyChoropleth";
+import LeafletChoropleth from "./LeafletChoropleth";
 
 import {
   computeMinimalBounds,
diff --git a/frontend/src/metabase/visualizations/components/FunnelBar.jsx b/frontend/src/metabase/visualizations/components/FunnelBar.jsx
index 1a2d7fa773e9b0df1b451b2c87cf27dfef02a857..08ba10ab99d4b207e8be632bbf562e62785ec808 100644
--- a/frontend/src/metabase/visualizations/components/FunnelBar.jsx
+++ b/frontend/src/metabase/visualizations/components/FunnelBar.jsx
@@ -2,7 +2,7 @@
 
 import React, { Component } from "react";
 
-import BarChart from "metabase/visualizations/visualizations/BarChart.jsx";
+import BarChart from "metabase/visualizations/visualizations/BarChart";
 
 import { getComputedSettingsForSeries } from "metabase/visualizations/lib/settings/visualization";
 import { assocIn } from "icepick";
diff --git a/frontend/src/metabase/visualizations/components/FunnelNormal.jsx b/frontend/src/metabase/visualizations/components/FunnelNormal.jsx
index 5593c7ad1f1062a695a73712f12b042b8a3c5e44..d66160acbfa5f09369b08db9b3311de7260b81b5 100644
--- a/frontend/src/metabase/visualizations/components/FunnelNormal.jsx
+++ b/frontend/src/metabase/visualizations/components/FunnelNormal.jsx
@@ -5,7 +5,7 @@ import React, { Component } from "react";
 import cx from "classnames";
 import styles from "./FunnelNormal.css";
 
-import Ellipsified from "metabase/components/Ellipsified.jsx";
+import Ellipsified from "metabase/components/Ellipsified";
 import { formatValue } from "metabase/lib/formatting";
 import { getFriendlyName } from "metabase/visualizations/lib/utils";
 
diff --git a/frontend/src/metabase/visualizations/components/LeafletChoropleth.jsx b/frontend/src/metabase/visualizations/components/LeafletChoropleth.jsx
index a61218f19645aaf92075ca5ca074cdd91b2f40d1..d33a47f158089b25e2df9ef66254ad069211ddb8 100644
--- a/frontend/src/metabase/visualizations/components/LeafletChoropleth.jsx
+++ b/frontend/src/metabase/visualizations/components/LeafletChoropleth.jsx
@@ -1,8 +1,8 @@
 import React from "react";
 
-import { normal } from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
-import CardRenderer from "./CardRenderer.jsx";
+import CardRenderer from "./CardRenderer";
 
 // import L from "leaflet";
 import "leaflet/dist/leaflet.css";
@@ -14,7 +14,7 @@ const LeafletChoropleth = ({
   series,
   geoJson,
   minimalBounds = computeMinimalBounds(geoJson.features),
-  getColor = () => normal.blue,
+  getColor = () => color("brand"),
   onHoverFeature = () => {},
   onClickFeature = () => {},
 }) => (
diff --git a/frontend/src/metabase/visualizations/components/LeafletGridHeatMap.jsx b/frontend/src/metabase/visualizations/components/LeafletGridHeatMap.jsx
index 1d88b8bd9a4071c5ddf4b13d09af14060c30d9f9..cdf4afb827944b6af336ad05be898f8ba75219f7 100644
--- a/frontend/src/metabase/visualizations/components/LeafletGridHeatMap.jsx
+++ b/frontend/src/metabase/visualizations/components/LeafletGridHeatMap.jsx
@@ -1,10 +1,10 @@
-import LeafletMap from "./LeafletMap.jsx";
+import LeafletMap from "./LeafletMap";
 import L from "leaflet";
 import { t } from "ttag";
 import d3 from "d3";
 
 import { rangeForValue } from "metabase/lib/dataset";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 export default class LeafletGridHeatMap extends LeafletMap {
   componentDidMount() {
@@ -26,11 +26,11 @@ export default class LeafletGridHeatMap extends LeafletMap {
         throw new Error(t`Grid map requires binned longitude/latitude.`);
       }
 
-      const color = d3.scale
+      const colorScale = d3.scale
         .linear()
         .domain([min, max])
         .interpolate(d3.interpolateHcl)
-        .range([d3.rgb(colors["success"]), d3.rgb(colors["error"])]);
+        .range([d3.rgb(color("success")), d3.rgb(color("error"))]);
 
       const gridSquares = gridLayer.getLayers();
       const totalSquares = Math.max(points.length, gridSquares.length);
@@ -45,7 +45,7 @@ export default class LeafletGridHeatMap extends LeafletMap {
         }
 
         if (i < points.length) {
-          gridSquares[i].setStyle({ color: color(points[i][2]) });
+          gridSquares[i].setStyle({ color: colorScale(points[i][2]) });
           const [latMin, latMax] = rangeForValue(points[i][0], latitudeColumn);
           const [lonMin, lonMax] = rangeForValue(points[i][1], longitudeColumn);
           gridSquares[i].setBounds([[latMin, lonMin], [latMax, lonMax]]);
diff --git a/frontend/src/metabase/visualizations/components/LeafletHeatMap.jsx b/frontend/src/metabase/visualizations/components/LeafletHeatMap.jsx
index 184efccd68ae046b8b23d765cbcdf8b77d4fb4f8..565e39be580905095e3a5086fcd25c3a3dc8ab87 100644
--- a/frontend/src/metabase/visualizations/components/LeafletHeatMap.jsx
+++ b/frontend/src/metabase/visualizations/components/LeafletHeatMap.jsx
@@ -1,4 +1,4 @@
-import LeafletMap from "./LeafletMap.jsx";
+import LeafletMap from "./LeafletMap";
 
 import L from "leaflet";
 import "leaflet.heat";
diff --git a/frontend/src/metabase/visualizations/components/LeafletMarkerPinMap.jsx b/frontend/src/metabase/visualizations/components/LeafletMarkerPinMap.jsx
index 322e9f63a666efe24100ae13dc9e38c78a49b2a1..0aa0cc1e6e747274722e484524440c3aea36a45f 100644
--- a/frontend/src/metabase/visualizations/components/LeafletMarkerPinMap.jsx
+++ b/frontend/src/metabase/visualizations/components/LeafletMarkerPinMap.jsx
@@ -1,4 +1,4 @@
-import LeafletMap from "./LeafletMap.jsx";
+import LeafletMap from "./LeafletMap";
 import L from "leaflet";
 
 import { isPK } from "metabase/lib/schema_metadata";
diff --git a/frontend/src/metabase/visualizations/components/LeafletTilePinMap.jsx b/frontend/src/metabase/visualizations/components/LeafletTilePinMap.jsx
index c4083497f2f000bd2e657ba11d53d53b08f8e8da..052da6ddd048fff8631a0a7b96b626687c0abf0f 100644
--- a/frontend/src/metabase/visualizations/components/LeafletTilePinMap.jsx
+++ b/frontend/src/metabase/visualizations/components/LeafletTilePinMap.jsx
@@ -1,4 +1,4 @@
-import LeafletMap from "./LeafletMap.jsx";
+import LeafletMap from "./LeafletMap";
 import L from "leaflet";
 
 export default class LeafletTilePinMap extends LeafletMap {
diff --git a/frontend/src/metabase/visualizations/components/LegendHorizontal.jsx b/frontend/src/metabase/visualizations/components/LegendHorizontal.jsx
index 2594968b122c49c8d961370d0e73f70f0c47c0bf..31ca1efb9778509666210ca0a3db13311979c64d 100644
--- a/frontend/src/metabase/visualizations/components/LegendHorizontal.jsx
+++ b/frontend/src/metabase/visualizations/components/LegendHorizontal.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import ReactDOM from "react-dom";
 import styles from "./Legend.css";
 
-import LegendItem from "./LegendItem.jsx";
+import LegendItem from "./LegendItem";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/visualizations/components/LegendItem.jsx b/frontend/src/metabase/visualizations/components/LegendItem.jsx
index d4d136bad3b82d1877a15e370ae283184d215ff3..a0d18eb5abc06788481d2173cf12835ae3684ac1 100644
--- a/frontend/src/metabase/visualizations/components/LegendItem.jsx
+++ b/frontend/src/metabase/visualizations/components/LegendItem.jsx
@@ -1,8 +1,8 @@
 import React, { Component } from "react";
 
-import Icon from "metabase/components/Icon.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
-import Ellipsified from "metabase/components/Ellipsified.jsx";
+import Icon from "metabase/components/Icon";
+import Tooltip from "metabase/components/Tooltip";
+import Ellipsified from "metabase/components/Ellipsified";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/visualizations/components/LegendVertical.jsx b/frontend/src/metabase/visualizations/components/LegendVertical.jsx
index 4db223065c3c7e0e3a4cceb05c5820393a4d0f9c..44642297d9acdb017488c93f86b765a2e30ae820 100644
--- a/frontend/src/metabase/visualizations/components/LegendVertical.jsx
+++ b/frontend/src/metabase/visualizations/components/LegendVertical.jsx
@@ -2,9 +2,9 @@ import React, { Component } from "react";
 import ReactDOM from "react-dom";
 import styles from "./Legend.css";
 import { t } from "ttag";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import Tooltip from "metabase/components/Tooltip";
 
-import LegendItem from "./LegendItem.jsx";
+import LegendItem from "./LegendItem";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx b/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
index 3cf11b5dee0883b153fdd11dc15683899fffe4b2..e6e2f2aef18e43b85823b12c9479157ebb75ca9a 100644
--- a/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
+++ b/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
@@ -3,9 +3,9 @@
 import React, { Component } from "react";
 import PropTypes from "prop-types";
 import { t } from "ttag";
-import CardRenderer from "./CardRenderer.jsx";
-import LegendHeader from "./LegendHeader.jsx";
-import { TitleLegendHeader } from "./TitleLegendHeader.jsx";
+import CardRenderer from "./CardRenderer";
+import LegendHeader from "./LegendHeader";
+import { TitleLegendHeader } from "./TitleLegendHeader";
 
 import "./LineAreaBarChart.css";
 
diff --git a/frontend/src/metabase/visualizations/components/MiniBar.jsx b/frontend/src/metabase/visualizations/components/MiniBar.jsx
index b2a2bc8bbd59b56b7de0bbd2b5ea5d74d77f8174..e816755e0d92be5fc1bd8b57a3ca79b77cd2c580 100644
--- a/frontend/src/metabase/visualizations/components/MiniBar.jsx
+++ b/frontend/src/metabase/visualizations/components/MiniBar.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import colors, { alpha } from "metabase/lib/colors";
+import { color, alpha } from "metabase/lib/colors";
 import { formatValue } from "metabase/lib/formatting";
 
 const BAR_HEIGHT = 8;
@@ -14,7 +14,7 @@ const MiniBar = ({ value, extent: [min, max], options, cellHeight }) => {
   const isNegative = value < 0;
   const barPercent =
     (Math.abs(value) / Math.max(Math.abs(min), Math.abs(max))) * 100;
-  const barColor = isNegative ? colors["error"] : colors["brand"];
+  const barColor = isNegative ? color("error") : color("brand");
 
   const barStyle = !hasNegative
     ? {
diff --git a/frontend/src/metabase/visualizations/components/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
index e6385b05c61b610c62ef51f70ca784e813f56e6c..7aae3be5523e0a8709900865286784b5556af119 100644
--- a/frontend/src/metabase/visualizations/components/TableInteractive.jsx
+++ b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
@@ -5,7 +5,7 @@ import PropTypes from "prop-types";
 import ReactDOM from "react-dom";
 import "./TableInteractive.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 import { formatValue } from "metabase/lib/formatting";
 import { isID, isFK } from "metabase/lib/schema_metadata";
@@ -22,13 +22,13 @@ import Dimension from "metabase-lib/lib/Dimension";
 import _ from "underscore";
 import cx from "classnames";
 
-import ExplicitSize from "metabase/components/ExplicitSize.jsx";
+import ExplicitSize from "metabase/components/ExplicitSize";
 import MiniBar from "./MiniBar";
 
 // $FlowFixMe: had to ignore react-virtualized in flow, probably due to different version
 import { Grid, ScrollSync } from "react-virtualized";
 import Draggable from "react-draggable";
-import Ellipsified from "metabase/components/Ellipsified.jsx";
+import Ellipsified from "metabase/components/Ellipsified";
 
 const HEADER_HEIGHT = 36;
 const ROW_HEIGHT = 36;
diff --git a/frontend/src/metabase/visualizations/components/TableSimple.jsx b/frontend/src/metabase/visualizations/components/TableSimple.jsx
index 74b6b1ab6b4f6f080d169997de0148363462be76..f962604e0e8179444ea84820bd3b1adcdd38e019 100644
--- a/frontend/src/metabase/visualizations/components/TableSimple.jsx
+++ b/frontend/src/metabase/visualizations/components/TableSimple.jsx
@@ -6,9 +6,9 @@ import ReactDOM from "react-dom";
 
 import styles from "./Table.css";
 
-import ExplicitSize from "metabase/components/ExplicitSize.jsx";
-import Ellipsified from "metabase/components/Ellipsified.jsx";
-import Icon from "metabase/components/Icon.jsx";
+import ExplicitSize from "metabase/components/ExplicitSize";
+import Ellipsified from "metabase/components/Ellipsified";
+import Icon from "metabase/components/Icon";
 import MiniBar from "./MiniBar";
 
 import { formatValue } from "metabase/lib/formatting";
diff --git a/frontend/src/metabase/visualizations/components/TitleLegendHeader.jsx b/frontend/src/metabase/visualizations/components/TitleLegendHeader.jsx
index 83d6b7835b19522274ac2fb5377bbc5cd231233e..706ca63ec8a371bf08c206d0816da6d969caed44 100644
--- a/frontend/src/metabase/visualizations/components/TitleLegendHeader.jsx
+++ b/frontend/src/metabase/visualizations/components/TitleLegendHeader.jsx
@@ -1,5 +1,5 @@
 import React from "react";
-import LegendHeader from "./LegendHeader.jsx";
+import LegendHeader from "./LegendHeader";
 import _ from "underscore";
 
 export const TitleLegendHeader = ({
diff --git a/frontend/src/metabase/visualizations/components/Visualization.jsx b/frontend/src/metabase/visualizations/components/Visualization.jsx
index 69350120ecec6cb2841b33137d76244bcdcac360..305dbeebb362fdbddae78e09e440264bb7d890b9 100644
--- a/frontend/src/metabase/visualizations/components/Visualization.jsx
+++ b/frontend/src/metabase/visualizations/components/Visualization.jsx
@@ -2,13 +2,13 @@
 
 import React from "react";
 
-import ExplicitSize from "metabase/components/ExplicitSize.jsx";
-import LegendHeader from "metabase/visualizations/components/LegendHeader.jsx";
-import ChartTooltip from "metabase/visualizations/components/ChartTooltip.jsx";
-import ChartClickActions from "metabase/visualizations/components/ChartClickActions.jsx";
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import Tooltip from "metabase/components/Tooltip.jsx";
+import ExplicitSize from "metabase/components/ExplicitSize";
+import LegendHeader from "metabase/visualizations/components/LegendHeader";
+import ChartTooltip from "metabase/visualizations/components/ChartTooltip";
+import ChartClickActions from "metabase/visualizations/components/ChartClickActions";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
+import Icon from "metabase/components/Icon";
+import Tooltip from "metabase/components/Tooltip";
 import { t, jt } from "ttag";
 import { duration, formatNumber } from "metabase/lib/formatting";
 import MetabaseAnalytics from "metabase/lib/analytics";
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingColorsPicker.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingColorsPicker.jsx
index b518cf2cb4d677c2b24a7eacd793528257165464..885d8401a34e504043a738057414a90df2a97431 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingColorsPicker.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingColorsPicker.jsx
@@ -1,6 +1,6 @@
 import React, { Component } from "react";
 
-import ChartSettingColorPicker from "./ChartSettingColorPicker.jsx";
+import ChartSettingColorPicker from "./ChartSettingColorPicker";
 
 export default class ChartSettingColorsPicker extends Component {
   render() {
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.jsx
index d7a6078067582d17802ece8e07e5e60b4a336634..b8b65e08e3f43ccd0373babe7e9f731f5e761fc7 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldPicker.jsx
@@ -6,7 +6,7 @@ import _ from "underscore";
 
 import Icon from "metabase/components/Icon";
 
-import ChartSettingSelect from "./ChartSettingSelect.jsx";
+import ChartSettingSelect from "./ChartSettingSelect";
 
 import { keyForColumn } from "metabase/lib/dataset";
 
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldsPicker.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldsPicker.jsx
index 6437bfebe2cb9899fd7d13216529052067c15229..cae9a6e25add8c63de21cb0886f8ee8cdba67b85 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldsPicker.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingFieldsPicker.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 import { t } from "ttag";
-import ChartSettingFieldPicker from "./ChartSettingFieldPicker.jsx";
+import ChartSettingFieldPicker from "./ChartSettingFieldPicker";
 
 const ChartSettingFieldsPicker = ({
   value = [],
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingGaugeSegments.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingGaugeSegments.jsx
index ed591ed495b36f60d8488b2047107ccababbc66d..6290c736cc83b4a9a2e3f74747e20a186955980d 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingGaugeSegments.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingGaugeSegments.jsx
@@ -3,7 +3,7 @@ import React from "react";
 import { t } from "ttag";
 import _ from "underscore";
 
-import colors, { normal } from "metabase/lib/colors";
+import { color, normal } from "metabase/lib/colors";
 
 import ColorPicker from "metabase/components/ColorPicker";
 import Button from "metabase/components/Button";
@@ -98,11 +98,11 @@ const ChartSettingGaugeSegments = ({ value: segments, onChange }) => {
 
 function getColorPalette() {
   return [
-    colors["error"],
-    colors["warning"],
-    colors["success"],
+    color("error"),
+    color("warning"),
+    color("success"),
     ...Object.values(normal).slice(0, 9),
-    colors["bg-medium"],
+    color("bg-medium"),
   ];
 }
 
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingInputGroup.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingInputGroup.jsx
index 8cc95fbbfef2f77f3bea8c56acec1df61f294b85..ed76486207d541878e4aafe87eb902f0c67c64cb 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingInputGroup.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingInputGroup.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import InputBlurChange from "metabase/components/InputBlurChange.jsx";
+import InputBlurChange from "metabase/components/InputBlurChange";
 
 // value is an array of strings. This component provides one input box per string
 export default function ChartSettingInputGroup({ value: values, onChange }) {
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingRadio.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingRadio.jsx
index 4b0d8c79cb44c5ae649e2ec64dde278ef5326b97..f238b69ce3db5999a80cea2c2c3a5ec4a5bf7172 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingRadio.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingRadio.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Radio from "metabase/components/Radio.jsx";
+import Radio from "metabase/components/Radio";
 
 const ChartSettingRadio = ({ value, onChange, options = [], className }) => (
   <Radio
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingSelect.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingSelect.jsx
index 02af84689dc38288e6a72b02c06f5d4a80f0f753..79be3df6411c567faeed072799aa1e82a5876d66 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingSelect.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingSelect.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Select, { Option } from "metabase/components/Select.jsx";
+import Select, { Option } from "metabase/components/Select";
 
 import cx from "classnames";
 
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingToggle.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingToggle.jsx
index 5a69458de752f1062949f892489c7c5658e8e7e6..f167c229641391df8cd8e4254a4950486449adab 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingToggle.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingToggle.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 
-import Toggle from "metabase/components/Toggle.jsx";
+import Toggle from "metabase/components/Toggle";
 
 const ChartSettingToggle = ({ value, onChange }) => (
   <Toggle value={value} onChange={onChange} />
diff --git a/frontend/src/metabase/visualizations/components/settings/ChartSettingsTableFormatting.jsx b/frontend/src/metabase/visualizations/components/settings/ChartSettingsTableFormatting.jsx
index 65e79803b6fdb007bdfcdec0026f949f7396f607..5369395f36f247b4fffb018b47cb62cfe82058cd 100644
--- a/frontend/src/metabase/visualizations/components/settings/ChartSettingsTableFormatting.jsx
+++ b/frontend/src/metabase/visualizations/components/settings/ChartSettingsTableFormatting.jsx
@@ -49,16 +49,16 @@ export const ALL_OPERATOR_NAMES = {
   ...STRING_OPERATOR_NAMES,
 };
 
-import colors, { desaturated } from "metabase/lib/colors";
+import { color, desaturated } from "metabase/lib/colors";
 
 const COLORS = Object.values(desaturated);
 const COLOR_RANGES = [].concat(
   ...COLORS.map(color => [["white", color], [color, "white"]]),
   [
-    [colors.error, "white", colors.success],
-    [colors.success, "white", colors.error],
-    [colors.error, colors.warning, colors.success],
-    [colors.success, colors.warning, colors.error],
+    [color("error"), "white", color("success")],
+    [color("success"), "white", color("error")],
+    [color("error"), color("warning"), color("success")],
+    [color("success"), color("warning"), color("error")],
   ],
 );
 
diff --git a/frontend/src/metabase/visualizations/index.js b/frontend/src/metabase/visualizations/index.js
index c03751c7c77edd04c4e94ea4bb562dddf6121e39..01f32feedae3f0293d4a6f2dc2948cc2a92d8cf8 100644
--- a/frontend/src/metabase/visualizations/index.js
+++ b/frontend/src/metabase/visualizations/index.js
@@ -1,21 +1,21 @@
 /* @flow weak */
 
-import Scalar from "./visualizations/Scalar.jsx";
-import SmartScalar from "./visualizations/SmartScalar.jsx";
-import Progress from "./visualizations/Progress.jsx";
-import Table from "./visualizations/Table.jsx";
-import Text from "./visualizations/Text.jsx";
-import LineChart from "./visualizations/LineChart.jsx";
-import BarChart from "./visualizations/BarChart.jsx";
-import RowChart from "./visualizations/RowChart.jsx";
-import PieChart from "./visualizations/PieChart.jsx";
-import AreaChart from "./visualizations/AreaChart.jsx";
-import ComboChart from "./visualizations/ComboChart.jsx";
-import MapViz from "./visualizations/Map.jsx";
-import ScatterPlot from "./visualizations/ScatterPlot.jsx";
-import Funnel from "./visualizations/Funnel.jsx";
-import Gauge from "./visualizations/Gauge.jsx";
-import ObjectDetail from "./visualizations/ObjectDetail.jsx";
+import Scalar from "./visualizations/Scalar";
+import SmartScalar from "./visualizations/SmartScalar";
+import Progress from "./visualizations/Progress";
+import Table from "./visualizations/Table";
+import Text from "./visualizations/Text";
+import LineChart from "./visualizations/LineChart";
+import BarChart from "./visualizations/BarChart";
+import RowChart from "./visualizations/RowChart";
+import PieChart from "./visualizations/PieChart";
+import AreaChart from "./visualizations/AreaChart";
+import ComboChart from "./visualizations/ComboChart";
+import MapViz from "./visualizations/Map";
+import ScatterPlot from "./visualizations/ScatterPlot";
+import Funnel from "./visualizations/Funnel";
+import Gauge from "./visualizations/Gauge";
+import ObjectDetail from "./visualizations/ObjectDetail";
 import { t } from "ttag";
 import _ from "underscore";
 
diff --git a/frontend/src/metabase/visualizations/lib/LineAreaBarPostRender.js b/frontend/src/metabase/visualizations/lib/LineAreaBarPostRender.js
index 0d791099e9c15894a1ca7f0f03429db94722bcaf..43bf5d2d083f383ef287e91baaefcef025df03f9 100644
--- a/frontend/src/metabase/visualizations/lib/LineAreaBarPostRender.js
+++ b/frontend/src/metabase/visualizations/lib/LineAreaBarPostRender.js
@@ -3,7 +3,7 @@
 import d3 from "d3";
 import _ from "underscore";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import { clipPathReference } from "metabase/lib/dom";
 import { adjustYAxisTicksIfNeeded } from "./apply_axis";
 
@@ -284,7 +284,7 @@ function onRenderCleanupGoalAndTrend(chart, onGoalHover, isSplitAxis) {
         y: y - 5,
         "text-anchor": labelOnRight ? "end" : "start",
         "font-weight": "bold",
-        fill: colors["text-medium"],
+        fill: color("text-medium"),
       })
       .on("mouseenter", function() {
         onGoalHover(this);
diff --git a/frontend/src/metabase/visualizations/lib/settings.js b/frontend/src/metabase/visualizations/lib/settings.js
index 9357547ad47de0b4b9436dad46faff2ae7da9870..0102d8ab9912404ba0a3cad35b1845e0f6b93481 100644
--- a/frontend/src/metabase/visualizations/lib/settings.js
+++ b/frontend/src/metabase/visualizations/lib/settings.js
@@ -1,16 +1,16 @@
 /* @flow */
 
-import ChartSettingInput from "metabase/visualizations/components/settings/ChartSettingInput.jsx";
-import ChartSettingInputGroup from "metabase/visualizations/components/settings/ChartSettingInputGroup.jsx";
-import ChartSettingInputNumeric from "metabase/visualizations/components/settings/ChartSettingInputNumeric.jsx";
-import ChartSettingRadio from "metabase/visualizations/components/settings/ChartSettingRadio.jsx";
-import ChartSettingSelect from "metabase/visualizations/components/settings/ChartSettingSelect.jsx";
-import ChartSettingToggle from "metabase/visualizations/components/settings/ChartSettingToggle.jsx";
-import ChartSettingButtonGroup from "metabase/visualizations/components/settings/ChartSettingButtonGroup.jsx";
-import ChartSettingFieldPicker from "metabase/visualizations/components/settings/ChartSettingFieldPicker.jsx";
-import ChartSettingFieldsPicker from "metabase/visualizations/components/settings/ChartSettingFieldsPicker.jsx";
-import ChartSettingColorPicker from "metabase/visualizations/components/settings/ChartSettingColorPicker.jsx";
-import ChartSettingColorsPicker from "metabase/visualizations/components/settings/ChartSettingColorsPicker.jsx";
+import ChartSettingInput from "metabase/visualizations/components/settings/ChartSettingInput";
+import ChartSettingInputGroup from "metabase/visualizations/components/settings/ChartSettingInputGroup";
+import ChartSettingInputNumeric from "metabase/visualizations/components/settings/ChartSettingInputNumeric";
+import ChartSettingRadio from "metabase/visualizations/components/settings/ChartSettingRadio";
+import ChartSettingSelect from "metabase/visualizations/components/settings/ChartSettingSelect";
+import ChartSettingToggle from "metabase/visualizations/components/settings/ChartSettingToggle";
+import ChartSettingButtonGroup from "metabase/visualizations/components/settings/ChartSettingButtonGroup";
+import ChartSettingFieldPicker from "metabase/visualizations/components/settings/ChartSettingFieldPicker";
+import ChartSettingFieldsPicker from "metabase/visualizations/components/settings/ChartSettingFieldsPicker";
+import ChartSettingColorPicker from "metabase/visualizations/components/settings/ChartSettingColorPicker";
+import ChartSettingColorsPicker from "metabase/visualizations/components/settings/ChartSettingColorsPicker";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
 
diff --git a/frontend/src/metabase/visualizations/visualizations/Gauge.jsx b/frontend/src/metabase/visualizations/visualizations/Gauge.jsx
index 71bf7362d1ded8c57013e1f95b07879464ee9fde..a972deef841ca4feca421c8be69196d543edc758 100644
--- a/frontend/src/metabase/visualizations/visualizations/Gauge.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Gauge.jsx
@@ -8,7 +8,7 @@ import cx from "classnames";
 
 import _ from "underscore";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import { formatValue } from "metabase/lib/formatting";
 import { isNumeric } from "metabase/lib/schema_metadata";
 import { columnSettings } from "metabase/visualizations/lib/settings/column";
@@ -30,10 +30,10 @@ const ARROW_BASE = ARROW_HEIGHT / Math.tan((64 / 180) * Math.PI);
 const ARROW_STROKE_THICKNESS = 1.25;
 
 // colors
-const BACKGROUND_ARC_COLOR = colors["bg-medium"];
-const SEGMENT_LABEL_COLOR = colors["text-dark"];
-const CENTER_LABEL_COLOR = colors["text-dark"];
-const ARROW_FILL_COLOR = colors["text-medium"];
+const BACKGROUND_ARC_COLOR = color("bg-medium");
+const SEGMENT_LABEL_COLOR = color("text-dark");
+const CENTER_LABEL_COLOR = color("text-dark");
+const ARROW_FILL_COLOR = color("text-medium");
 const ARROW_STROKE_COLOR = "white";
 
 // in ems, but within the scaled 100px SVG element
@@ -119,9 +119,9 @@ export default class Gauge extends Component {
           value = series[0].data.rows[0][0];
         } catch (e) {}
         return [
-          { min: 0, max: value / 2, color: colors["error"], label: "" },
-          { min: value / 2, max: value, color: colors["warning"], label: "" },
-          { min: value, max: value * 2, color: colors["success"], label: "" },
+          { min: 0, max: value / 2, color: color("error"), label: "" },
+          { min: value / 2, max: value, color: color("warning"), label: "" },
+          { min: value, max: value * 2, color: color("success"), label: "" },
         ];
       },
       widget: ChartSettingGaugeSegments,
@@ -399,7 +399,7 @@ const GaugeSegmentLabel = ({ position: [x, y], style = {}, children }) => (
     x={x}
     y={y}
     style={{
-      fill: colors["text-medium"],
+      fill: color("text-medium"),
       fontSize: `${FONT_SIZE_SEGMENT_LABEL}em`,
       textAnchor: Math.abs(x) < 5 ? "middle" : x > 0 ? "start" : "end",
       // shift text in the lower half down a bit
diff --git a/frontend/src/metabase/visualizations/visualizations/Map.jsx b/frontend/src/metabase/visualizations/visualizations/Map.jsx
index c08876010801e1c36bc83e5b85929231059ff705..44782555bc9a2038f51fb4bf4f8915a93e65a7e0 100644
--- a/frontend/src/metabase/visualizations/visualizations/Map.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Map.jsx
@@ -4,8 +4,8 @@ import React, { Component } from "react";
 import { t } from "ttag";
 import ChoroplethMap, {
   getColorplethColorScale,
-} from "../components/ChoroplethMap.jsx";
-import PinMap from "../components/PinMap.jsx";
+} from "../components/ChoroplethMap";
+import PinMap from "../components/PinMap";
 
 import { ChartSettingsError } from "metabase/visualizations/lib/errors";
 import {
diff --git a/frontend/src/metabase/visualizations/visualizations/ObjectDetail.jsx b/frontend/src/metabase/visualizations/visualizations/ObjectDetail.jsx
index 878d8c77bb09d59b3cfad327ec28644695395400..9fd94bf8fab5498525e567b88e5e8309202835d9 100644
--- a/frontend/src/metabase/visualizations/visualizations/ObjectDetail.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/ObjectDetail.jsx
@@ -4,10 +4,10 @@ import React, { Component } from "react";
 import { connect } from "react-redux";
 import { t, jt } from "ttag";
 import DirectionalButton from "metabase/components/DirectionalButton";
-import ExpandableString from "metabase/query_builder/components/ExpandableString.jsx";
-import Icon from "metabase/components/Icon.jsx";
-import IconBorder from "metabase/components/IconBorder.jsx";
-import LoadingSpinner from "metabase/components/LoadingSpinner.jsx";
+import ExpandableString from "metabase/query_builder/components/ExpandableString";
+import Icon from "metabase/components/Icon";
+import IconBorder from "metabase/components/IconBorder";
+import LoadingSpinner from "metabase/components/LoadingSpinner";
 
 import {
   isID,
diff --git a/frontend/src/metabase/visualizations/visualizations/PieChart.jsx b/frontend/src/metabase/visualizations/visualizations/PieChart.jsx
index b6dd579da7ee2b7f34f25016f3172dd3698d8c27..85e5c226dc2e421d02c2c6a0f289a9d474380d30 100644
--- a/frontend/src/metabase/visualizations/visualizations/PieChart.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/PieChart.jsx
@@ -4,8 +4,8 @@ import React, { Component } from "react";
 import ReactDOM from "react-dom";
 import styles from "./PieChart.css";
 import { t } from "ttag";
-import ChartTooltip from "../components/ChartTooltip.jsx";
-import ChartWithLegend from "../components/ChartWithLegend.jsx";
+import ChartTooltip from "../components/ChartTooltip";
+import ChartWithLegend from "../components/ChartWithLegend";
 
 import {
   ChartSettingsError,
@@ -23,7 +23,7 @@ import { columnSettings } from "metabase/visualizations/lib/settings/column";
 
 import { formatValue } from "metabase/lib/formatting";
 
-import colors, { getColorsForValues } from "metabase/lib/colors";
+import { color, getColorsForValues } from "metabase/lib/colors";
 
 import cx from "classnames";
 
@@ -267,7 +267,7 @@ export default class PieChart extends Component {
             key: "Other",
             value: otherTotal,
             percentage: otherTotal / total,
-            color: colors["text-light"],
+            color: color("text-light"),
           };
     if (otherSlice.value > 0) {
       // increase "other" slice so it's barely visible
@@ -303,7 +303,7 @@ export default class PieChart extends Component {
     if (slices.length === 0) {
       otherSlice = {
         value: 1,
-        color: colors["text-light"],
+        color: color("text-light"),
         noHover: true,
       };
       slices.push(otherSlice);
diff --git a/frontend/src/metabase/visualizations/visualizations/Progress.jsx b/frontend/src/metabase/visualizations/visualizations/Progress.jsx
index d98a3e4c09aa0326e7c3fc6c75597a999076b1c9..50c1da1334800723adbdffd2211e496fc3003fc5 100644
--- a/frontend/src/metabase/visualizations/visualizations/Progress.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Progress.jsx
@@ -5,9 +5,9 @@ import ReactDOM from "react-dom";
 import { t } from "ttag";
 import { formatValue } from "metabase/lib/formatting";
 import { isNumeric } from "metabase/lib/schema_metadata";
-import Icon from "metabase/components/Icon.jsx";
-import IconBorder from "metabase/components/IconBorder.jsx";
-import { normal } from "metabase/lib/colors";
+import Icon from "metabase/components/Icon";
+import IconBorder from "metabase/components/IconBorder";
+import { color } from "metabase/lib/colors";
 
 import _ from "underscore";
 
@@ -67,7 +67,7 @@ export default class Progress extends Component {
       section: t`Display`,
       title: t`Color`,
       widget: "color",
-      default: normal.green,
+      default: color("accent1"),
     },
   };
 
diff --git a/frontend/src/metabase/visualizations/visualizations/SmartScalar.jsx b/frontend/src/metabase/visualizations/visualizations/SmartScalar.jsx
index cc1de87f9829f6ee283116e63eabc53583d030d7..902fb4aa67f85ea7cef8710e288b8171393942d3 100644
--- a/frontend/src/metabase/visualizations/visualizations/SmartScalar.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/SmartScalar.jsx
@@ -4,7 +4,7 @@ import { t, jt } from "ttag";
 import _ from "underscore";
 
 import { formatNumber, formatValue } from "metabase/lib/formatting";
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 
 import Icon from "metabase/components/Icon";
 
@@ -107,15 +107,14 @@ export default class Smart extends React.Component {
 
     const change = formatNumber(lastChange * 100);
     const isNegative = (change && Math.sign(change) < 0) || false;
-
-    let color = isNegative ? colors["error"] : colors["success"];
+    const isSwapped = settings["scalar.switch_positive_negative"];
 
     // if the number is negative but thats been identified as a good thing (e.g. decreased latency somehow?)
-    if (isNegative && settings["scalar.switch_positive_negative"]) {
-      color = colors["success"];
-    } else if (!isNegative && settings["scalar.switch_positive_negative"]) {
-      color = colors["error"];
-    }
+    const changeColor = (isSwapped
+    ? !isNegative
+    : isNegative)
+      ? color("error")
+      : color("success");
 
     const changeDisplay = (
       <span style={{ fontWeight: 900 }}>{Math.abs(change)}%</span>
@@ -123,7 +122,7 @@ export default class Smart extends React.Component {
     const separator = (
       <span
         style={{
-          color: colors["text-light"],
+          color: color("text-light"),
           fontSize: "0.7rem",
           marginLeft: 4,
           marginRight: 4,
@@ -181,11 +180,11 @@ export default class Smart extends React.Component {
           {!lastChange || !previousValue ? (
             <Box
               className="text-centered text-bold mt1"
-              color={colors["text-medium"]}
+              color={color("text-medium")}
             >{jt`Nothing to compare for the previous ${granularity}.`}</Box>
           ) : (
             <Flex align="center" mt={1} flexWrap="wrap">
-              <Flex align="center" color={color}>
+              <Flex align="center" color={changeColor}>
                 <Icon name={isNegative ? "arrow_down" : "arrow_up"} />
                 {changeDisplay}
               </Flex>
@@ -193,7 +192,7 @@ export default class Smart extends React.Component {
                 id="SmartScalar-PreviousValue"
                 className="flex align-center hide lg-show"
                 style={{
-                  color: colors["text-medium"],
+                  color: color("text-medium"),
                 }}
               >
                 {!isFullscreen &&
diff --git a/frontend/src/metabase/visualizations/visualizations/Table.jsx b/frontend/src/metabase/visualizations/visualizations/Table.jsx
index f899f39d698aa83577933af595299e3b4380afe8..e5e2fd175f1c116b55556ff657b4fec17d321d9e 100644
--- a/frontend/src/metabase/visualizations/visualizations/Table.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Table.jsx
@@ -3,7 +3,7 @@
 import React, { Component } from "react";
 
 import TableInteractive from "../components/TableInteractive.jsx";
-import TableSimple from "../components/TableSimple.jsx";
+import TableSimple from "../components/TableSimple";
 import { t } from "ttag";
 import * as DataGrid from "metabase/lib/data_grid";
 import { findColumnIndexForColumnSetting } from "metabase/lib/dataset";
@@ -22,10 +22,10 @@ import {
   isImageURL,
   isAvatarURL,
 } from "metabase/lib/schema_metadata";
-import ChartSettingOrderedColumns from "metabase/visualizations/components/settings/ChartSettingOrderedColumns.jsx";
+import ChartSettingOrderedColumns from "metabase/visualizations/components/settings/ChartSettingOrderedColumns";
 import ChartSettingsTableFormatting, {
   isFormattable,
-} from "metabase/visualizations/components/settings/ChartSettingsTableFormatting.jsx";
+} from "metabase/visualizations/components/settings/ChartSettingsTableFormatting";
 
 import { makeCellBackgroundGetter } from "metabase/visualizations/lib/table_format";
 import { columnSettings } from "metabase/visualizations/lib/settings/column";
diff --git a/frontend/src/metabase/visualizations/visualizations/Text.jsx b/frontend/src/metabase/visualizations/visualizations/Text.jsx
index 4e0a869adfd8d090c43e8531f9395e1ce2e4692a..51096b844a5e48a4132cc4dae9765267a2ee16ad 100644
--- a/frontend/src/metabase/visualizations/visualizations/Text.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Text.jsx
@@ -4,7 +4,7 @@ import React, { Component } from "react";
 import ReactMarkdown from "react-markdown";
 import styles from "./Text.css";
 
-import Icon from "metabase/components/Icon.jsx";
+import Icon from "metabase/components/Icon";
 
 import cx from "classnames";
 import { t } from "ttag";
diff --git a/frontend/test/__support__/mocks.js b/frontend/test/__support__/mocks.js
index f498fa869e48ad07e376fb133f8cde7849288d0a..f8ce89b75e29e72e63e1cdc4534d4d26482c4b91 100644
--- a/frontend/test/__support__/mocks.js
+++ b/frontend/test/__support__/mocks.js
@@ -38,7 +38,7 @@ modal.default = modal.TestModal;
 import * as tooltip from "metabase/components/Tooltip";
 tooltip.default = tooltip.TestTooltip;
 
-jest.mock("metabase/components/Popover.jsx");
+jest.mock("metabase/components/Popover");
 
 import * as bodyComponent from "metabase/components/BodyComponent";
 bodyComponent.default = bodyComponent.TestBodyComponent;
diff --git a/frontend/test/metabase-lib/lib/Dimension.unit.spec.js b/frontend/test/metabase-lib/lib/Dimension.unit.spec.js
index 8419ac673ea1a796e3d4ac207c373ca0f92ba293..7730a00590dda9ccaa741ecca36a5d19806be9fe 100644
--- a/frontend/test/metabase-lib/lib/Dimension.unit.spec.js
+++ b/frontend/test/metabase-lib/lib/Dimension.unit.spec.js
@@ -106,14 +106,15 @@ describe("Dimension", () => {
           expect(Dimension.parseMBQL(["field-id", 1], metadata).mbql()).toEqual(
             ["field-id", 1],
           );
-          expect(Dimension.parseMBQL(["fk->", 1, 2], metadata).mbql()).toEqual([
-            "fk->",
-            ["field-id", 1],
-            ["field-id", 2],
-          ]);
           expect(
             Dimension.parseMBQL(
-              ["datetime-field", 1, "month"],
+              ["fk->", ["field-id", 1], ["field-id", 2]],
+              metadata,
+            ).mbql(),
+          ).toEqual(["fk->", ["field-id", 1], ["field-id", 2]]);
+          expect(
+            Dimension.parseMBQL(
+              ["datetime-field", ["field-id", 1], "month"],
               metadata,
             ).mbql(),
           ).toEqual(["datetime-field", ["field-id", 1], "month"]);
@@ -149,13 +150,22 @@ describe("Dimension", () => {
           expect(d1.isEqual(1)).toEqual(true);
         });
         it("returns false for different type clauses", () => {
-          const d1 = Dimension.parseMBQL(["fk->", 1, 2], metadata);
+          const d1 = Dimension.parseMBQL(
+            ["fk->", ["field-id", 1], ["field-id", 2]],
+            metadata,
+          );
           const d2 = Dimension.parseMBQL(["field-id", 1], metadata);
           expect(d1.isEqual(d2)).toEqual(false);
         });
         it("returns false for same type clauses with different arguments", () => {
-          const d1 = Dimension.parseMBQL(["fk->", 1, 2], metadata);
-          const d2 = Dimension.parseMBQL(["fk->", 1, 3], metadata);
+          const d1 = Dimension.parseMBQL(
+            ["fk->", ["field-id", 1], ["field-id", 2]],
+            metadata,
+          );
+          const d2 = Dimension.parseMBQL(
+            ["fk->", ["field-id", 1], ["field-id", 3]],
+            metadata,
+          );
           expect(d1.isEqual(d2)).toEqual(false);
         });
       });
diff --git a/frontend/test/metabase-lib/lib/queries/StructuredQuery-nesting.unit.spec.js b/frontend/test/metabase-lib/lib/queries/StructuredQuery-nesting.unit.spec.js
index 9f15af67f2b8715817e8ba73a757c7aa5e50906d..297eb2edeb45e10c06bc704dc1612cfd15712c54 100644
--- a/frontend/test/metabase-lib/lib/queries/StructuredQuery-nesting.unit.spec.js
+++ b/frontend/test/metabase-lib/lib/queries/StructuredQuery-nesting.unit.spec.js
@@ -48,7 +48,7 @@ describe("StructuredQuery nesting", () => {
     it("should return a table with correct dimensions", () => {
       const q = makeStructuredQuery({
         "source-table": ORDERS_TABLE_ID,
-        aggregation: ["count"],
+        aggregation: [["count"]],
         breakout: [["field-id", ORDERS_PRODUCT_FK_FIELD_ID]],
       });
       expect(
diff --git a/frontend/test/metabase/admin/people/containers/PeopleListingApp.integ.spec.js b/frontend/test/metabase/admin/people/containers/PeopleListingApp.integ.spec.js
index fbf1a43762dbed26f7e7c1d3a10c63892ecd1adb..954fc21c54426c9b05b23220cb23b1692a2a3a64 100644
--- a/frontend/test/metabase/admin/people/containers/PeopleListingApp.integ.spec.js
+++ b/frontend/test/metabase/admin/people/containers/PeopleListingApp.integ.spec.js
@@ -3,7 +3,7 @@ import mock from "xhr-mock";
 import { mountWithStore } from "__support__/integration_tests";
 import { click } from "__support__/enzyme_utils";
 import { refreshCurrentUser } from "metabase/redux/user";
-import UserAvatar from "metabase/components/UserAvatar.jsx";
+import UserAvatar from "metabase/components/UserAvatar";
 import Radio from "metabase/components/Radio";
 import EntityMenu from "metabase/components/EntityMenu";
 import EntityMenuItem from "metabase/components/EntityMenuItem";
diff --git a/frontend/test/metabase/admin/settings/SettingsAuthenticationOptions.e2e.spec.js b/frontend/test/metabase/admin/settings/SettingsAuthenticationOptions.e2e.spec.js
index 3486d41e1ad417bb09c0b7d64ec38aec5e172aa8..1c5f085da639ef2ebdfc914326e980535a565a9f 100644
--- a/frontend/test/metabase/admin/settings/SettingsAuthenticationOptions.e2e.spec.js
+++ b/frontend/test/metabase/admin/settings/SettingsAuthenticationOptions.e2e.spec.js
@@ -5,8 +5,8 @@ import { mount } from "enzyme";
 
 import SettingsEditorApp from "metabase/admin/settings/containers/SettingsEditorApp";
 import SettingsAuthenticationOptions from "metabase/admin/settings/components/SettingsAuthenticationOptions";
-import SettingsSingleSignOnForm from "metabase/admin/settings/components/SettingsSingleSignOnForm.jsx";
-import SettingsLdapForm from "metabase/admin/settings/components/SettingsLdapForm.jsx";
+import SettingsSingleSignOnForm from "metabase/admin/settings/components/SettingsSingleSignOnForm";
+import SettingsLdapForm from "metabase/admin/settings/components/SettingsLdapForm";
 
 import { INITIALIZE_SETTINGS } from "metabase/admin/settings/settings";
 
diff --git a/frontend/test/metabase/auth/containers/LoginApp.unit.spec.js b/frontend/test/metabase/auth/containers/LoginApp.unit.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..c48edd8b889a7eacb20e41cfe54b251515e65a81
--- /dev/null
+++ b/frontend/test/metabase/auth/containers/LoginApp.unit.spec.js
@@ -0,0 +1,57 @@
+import React from "react";
+
+import LoginApp from "metabase/auth/containers/LoginApp";
+
+import { mountWithStore } from "__support__/integration_tests";
+
+jest.mock("metabase/lib/settings", () => ({
+  get: () => ({
+    tag: 1,
+    version: 1,
+  }),
+  ssoEnabled: jest.fn(),
+  ldapEnabled: jest.fn(),
+}));
+
+import Settings from "metabase/lib/settings";
+
+describe("LoginApp", () => {
+  describe("initial state", () => {
+    describe("without SSO", () => {
+      it("should show the login form", () => {
+        const { wrapper } = mountWithStore(
+          <LoginApp location={{ query: {} }} />,
+        );
+        expect(wrapper.find("FormField").length).toBe(2);
+      });
+    });
+    describe("with SSO", () => {
+      beforeEach(() => {
+        Settings.ssoEnabled.mockReturnValue(true);
+      });
+      it("should show the SSO button", () => {
+        const { wrapper } = mountWithStore(
+          <LoginApp location={{ query: {} }} />,
+        );
+        expect(wrapper.find("SSOLoginButton").length).toBe(1);
+        expect(wrapper.find(".Button.EmailSignIn").length).toBe(1);
+      });
+
+      it("should hide the login form initially", () => {
+        const { wrapper } = mountWithStore(
+          <LoginApp location={{ query: {} }} />,
+        );
+        expect(wrapper.find("FormField").length).toBe(0);
+      });
+
+      it("should show the login form if the url param is set", () => {
+        const { wrapper } = mountWithStore(
+          <LoginApp location={{ query: { useMBLogin: true } }} />,
+        );
+
+        expect(wrapper.find("FormField").length).toBe(2);
+        expect(wrapper.find("SSOLoginButton").length).toBe(0);
+      });
+    });
+  });
+});
diff --git a/frontend/test/metabase/components/DatabaseDetailsForm.unit.spec.js b/frontend/test/metabase/components/DatabaseDetailsForm.unit.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..c6b7d5b9198c06eb557ec6fea23806f8b79d819e
--- /dev/null
+++ b/frontend/test/metabase/components/DatabaseDetailsForm.unit.spec.js
@@ -0,0 +1,56 @@
+import React from "react";
+import { mount } from "enzyme";
+
+import DatabaseDetailsForm from "metabase/components/DatabaseDetailsForm";
+
+const ENGINES = {
+  h2: {
+    "details-fields": [
+      {
+        name: "db",
+        "display-name": "Connection String",
+        placeholder: "file:/Users/camsaul/bird_sightings/toucans",
+        required: true,
+      },
+    ],
+    "driver-name": "H2",
+  },
+};
+
+const DEFAULT_PROPS = {
+  details: {},
+  engines: ENGINES,
+  engine: Object.keys(ENGINES)[0],
+  submitButtonText: "Next",
+  submitFn: () => undefined,
+};
+
+describe("DatabaseDetailsForm", () => {
+  it("should render", () => {
+    mount(<DatabaseDetailsForm {...DEFAULT_PROPS} />);
+  });
+
+  it("should render field errors", () => {
+    const wrapper = mount(
+      <DatabaseDetailsForm
+        {...DEFAULT_PROPS}
+        formError={{ data: { errors: { db: "fix this field" } } }}
+      />,
+    );
+    const labels = wrapper.find(".Form-label").map(e => e.text());
+    expect(labels).toContain("Connection String : fix this field");
+  });
+
+  it("should render field errors as a form message if there's no matching field", () => {
+    const wrapper = mount(
+      <DatabaseDetailsForm
+        {...DEFAULT_PROPS}
+        formError={{
+          data: { errors: { foobar: "couldn't find a field for this" } },
+        }}
+      />,
+    );
+    const message = wrapper.find(".Form-message").text();
+    expect(message).toEqual("couldn't find a field for this");
+  });
+});
diff --git a/frontend/test/metabase/dashboard/DashCard.unit.spec.js b/frontend/test/metabase/dashboard/DashCard.unit.spec.js
index 38231591e0b0d1d81d2c87281cfe16bd1b8827d4..a121476e94b58953fce0a17d877b6efc6a60619e 100644
--- a/frontend/test/metabase/dashboard/DashCard.unit.spec.js
+++ b/frontend/test/metabase/dashboard/DashCard.unit.spec.js
@@ -5,7 +5,7 @@ import { assocIn } from "icepick";
 
 import DashCard from "metabase/dashboard/components/DashCard";
 
-jest.mock("metabase/visualizations/components/Visualization.jsx");
+jest.mock("metabase/visualizations/components/Visualization");
 
 const DEFAULT_PROPS = {
   dashcard: {
diff --git a/frontend/test/metabase/dashboard/dashboard.e2e.spec.js b/frontend/test/metabase/dashboard/dashboard.e2e.spec.js
index ddfd442c3359efb0a97fb7e1e08fd24fbc571c6e..285e9330069329d0e79008da3ad958d5ed903cb5 100644
--- a/frontend/test/metabase/dashboard/dashboard.e2e.spec.js
+++ b/frontend/test/metabase/dashboard/dashboard.e2e.spec.js
@@ -71,7 +71,7 @@ const mockPublicDashboardResponse = {
         {
           parameter_id: "598ab323",
           card_id: 25,
-          target: ["dimension", ["fk->", 3, 21]],
+          target: ["dimension", ["fk->", ["field-id", 3], ["field-id", 21]]],
         },
       ],
       card_id: 25,
diff --git a/frontend/test/metabase/lib/dataset.unit.spec.js b/frontend/test/metabase/lib/dataset.unit.spec.js
index eb9a1bcf1ab30190df66ff1a19a134caccbb9584..4d35f3bf47599aa902ced09c6ed5bfd1bbe4ae69 100644
--- a/frontend/test/metabase/lib/dataset.unit.spec.js
+++ b/frontend/test/metabase/lib/dataset.unit.spec.js
@@ -21,7 +21,7 @@ describe("metabase/util/dataset", () => {
     it('should return `["field-id", 1]` for a normal column', () => {
       expect(fieldRefForColumn(FIELD_COLUMN)).toEqual(["field-id", 1]);
     });
-    it('should return `["fk->", 2, 1]` for a fk column', () => {
+    it('should return `["fk->", ["field-id", 2], ["field-id", 1]]` for a fk column', () => {
       expect(fieldRefForColumn(FK_COLUMN)).toEqual([
         "fk->",
         ["field-id", 2],
@@ -233,7 +233,7 @@ describe("metabase/util/dataset", () => {
     });
     it("should find column with non-normalized fieldRef", () => {
       const column = findColumnForColumnSetting(columns, {
-        fieldRef: ["fk->", 2, 1],
+        fieldRef: ["fk->", 2, 1], // deprecated
       });
       expect(column).toBe(columns[1]);
     });
diff --git a/frontend/test/metabase/lib/formatting.unit.spec.js b/frontend/test/metabase/lib/formatting.unit.spec.js
index 03e2a3ea099b426be9a22204ace1be6b5bd9511b..d125f1294d118b91e6ca6cf8ee7866e593f2efef 100644
--- a/frontend/test/metabase/lib/formatting.unit.spec.js
+++ b/frontend/test/metabase/lib/formatting.unit.spec.js
@@ -7,7 +7,7 @@ import {
   formatUrl,
   formatDateTimeWithUnit,
 } from "metabase/lib/formatting";
-import ExternalLink from "metabase/components/ExternalLink.jsx";
+import ExternalLink from "metabase/components/ExternalLink";
 import { TYPE } from "metabase/lib/types";
 
 describe("formatting", () => {
diff --git a/frontend/test/metabase/lib/query.unit.spec.js b/frontend/test/metabase/lib/query.unit.spec.js
index c0cc42ca48fc0d1e14124e9584a921845351e652..e15514942bff140149209efabd460fba50e54b11 100644
--- a/frontend/test/metabase/lib/query.unit.spec.js
+++ b/frontend/test/metabase/lib/query.unit.spec.js
@@ -70,20 +70,14 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should not remove complete sort clauses", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["rows"],
-        breakout: [],
-        filter: [],
-        "order-by": [["asc", 1]],
+        "order-by": [["asc", ["field-id", 1]]],
       };
       Q_DEPRECATED.cleanQuery(query);
-      expect(query["order-by"]).toEqual([["asc", 1]]);
+      expect(query["order-by"]).toEqual([["asc", ["field-id", 1]]]);
     });
     it("should remove incomplete sort clauses", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["rows"],
-        breakout: [],
-        filter: [],
         "order-by": [["asc", null]],
       };
       Q_DEPRECATED.cleanQuery(query);
@@ -93,9 +87,8 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should not remove sort clauses on aggregations if that aggregation supports it", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
+        aggregation: [["count"]],
         breakout: [["field-id", 1]],
-        filter: [],
         "order-by": [["asc", ["aggregation", 0]]],
       };
       Q_DEPRECATED.cleanQuery(query);
@@ -104,9 +97,6 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should remove sort clauses on aggregations if that aggregation doesn't support it", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["rows"],
-        breakout: [],
-        filter: [],
         "order-by": [["asc", ["aggregation", 0]]],
       };
       Q_DEPRECATED.cleanQuery(query);
@@ -116,9 +106,8 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should not remove sort clauses on fields appearing in breakout", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
+        aggregation: [["count"]],
         breakout: [["field-id", 1]],
-        filter: [],
         "order-by": [["asc", ["field-id", 1]]],
       };
       Q_DEPRECATED.cleanQuery(query);
@@ -127,10 +116,8 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should remove sort clauses on fields not appearing in breakout", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
-        breakout: [],
-        filter: [],
-        "order-by": [["asc", 1]],
+        aggregation: [["count"]],
+        "order-by": [["asc", ["field-id", 1]]],
       };
       Q_DEPRECATED.cleanQuery(query);
       expect(query["order-by"]).toEqual(undefined);
@@ -139,53 +126,53 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should not remove sort clauses with foreign keys on fields appearing in breakout", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
-        breakout: [["fk->", 1, 2]],
-        filter: [],
-        "order-by": [["asc", ["fk->", 1, 2]]],
+        aggregation: [["count"]],
+        breakout: [["fk->", ["field-id", 1], ["field-id", 2]]],
+        "order-by": [["asc", ["fk->", ["field-id", 1], ["field-id", 2]]]],
       };
       Q_DEPRECATED.cleanQuery(query);
-      expect(query["order-by"]).toEqual([["asc", ["fk->", 1, 2]]]);
+      expect(query["order-by"]).toEqual([
+        ["asc", ["fk->", ["field-id", 1], ["field-id", 2]]],
+      ]);
     });
 
     it("should not remove sort clauses with datetime-fields on fields appearing in breakout", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
-        breakout: [["datetime-field", 1, "as", "week"]],
-        filter: [],
-        "order-by": [["asc", ["datetime-field", 1, "as", "week"]]],
+        aggregation: [["count"]],
+        breakout: [["datetime-field", ["field-id", 1], "week"]],
+        "order-by": [["asc", ["datetime-field", ["field-id", 1], "week"]]],
       };
       Q_DEPRECATED.cleanQuery(query);
       expect(query["order-by"]).toEqual([
-        ["asc", ["datetime-field", 1, "as", "week"]],
+        ["asc", ["datetime-field", ["field-id", 1], "week"]],
       ]);
     });
 
     it("should replace order-by clauses with the exact matching datetime-fields version in the breakout", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
-        breakout: [["datetime-field", 1, "as", "week"]],
-        filter: [],
-        "order-by": [["asc", 1]],
+        aggregation: [["count"]],
+        breakout: [["datetime-field", ["field-id", 1], "week"]],
+        "order-by": [["asc", ["field-id", 1]]],
       };
       Q_DEPRECATED.cleanQuery(query);
       expect(query["order-by"]).toEqual([
-        ["asc", ["datetime-field", 1, "as", "week"]],
+        ["asc", ["datetime-field", ["field-id", 1], "week"]],
       ]);
     });
 
     it("should replace order-by clauses with the exact matching fk-> version in the breakout", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
-        breakout: [["fk->", 1, 2]],
-        filter: [],
-        "order-by": [["asc", 2]],
+        aggregation: [["count"]],
+        breakout: [["fk->", ["field-id", 1], ["field-id", 2]]],
+        "order-by": [["asc", ["field-id", 2]]],
       };
       Q_DEPRECATED.cleanQuery(query);
-      expect(query["order-by"]).toEqual([["asc", ["fk->", 1, 2]]]);
+      expect(query["order-by"]).toEqual([
+        ["asc", ["fk->", ["field-id", 1], ["field-id", 2]]],
+      ]);
     });
   });
 
@@ -193,9 +180,8 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should not mutate the query", () => {
       const query = {
         "source-table": 0,
-        aggregation: ["count"],
+        aggregation: [["count"]],
         breakout: [["field-id", 1]],
-        filter: [],
       };
       Q_DEPRECATED.removeBreakout(query, 0);
       expect(query.breakout).toEqual([["field-id", 1]]);
@@ -203,9 +189,8 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should remove the dimension", () => {
       let query = {
         "source-table": 0,
-        aggregation: ["count"],
+        aggregation: [["count"]],
         breakout: [["field-id", 1]],
-        filter: [],
       };
       query = Q_DEPRECATED.removeBreakout(query, 0);
       expect(query.breakout).toEqual(undefined);
@@ -213,10 +198,9 @@ describe("Legacy Q_DEPRECATED library", () => {
     it("should remove sort clauses for the dimension that was removed", () => {
       let query = {
         "source-table": 0,
-        aggregation: ["count"],
+        aggregation: [["count"]],
         breakout: [["field-id", 1]],
-        filter: [],
-        "order-by": [["asc", 1]],
+        "order-by": [["asc", ["field-id", 1]]],
       };
       query = Q_DEPRECATED.removeBreakout(query, 0);
       expect(query["order-by"]).toEqual(undefined);
@@ -262,7 +246,7 @@ describe("Legacy Q_DEPRECATED library", () => {
     });
     it("should return unit object for old-style datetime-field", () => {
       const target = Q_DEPRECATED.getFieldTarget(
-        ["datetime-field", 1, "as", "day"],
+        ["datetime-field", ["field-id", 1], "day"],
         table1,
       );
       expect(target.table).toEqual(table1);
@@ -272,7 +256,7 @@ describe("Legacy Q_DEPRECATED library", () => {
     });
     it("should return unit object for new-style datetime-field", () => {
       const target = Q_DEPRECATED.getFieldTarget(
-        ["datetime-field", 1, "as", "day"],
+        ["datetime-field", ["field-id", 1], "day"],
         table1,
       );
       expect(target.table).toEqual(table1);
@@ -282,7 +266,10 @@ describe("Legacy Q_DEPRECATED library", () => {
     });
 
     it("should return field object and table for old-style fk field", () => {
-      const target = Q_DEPRECATED.getFieldTarget(["fk->", 1, 2], table1);
+      const target = Q_DEPRECATED.getFieldTarget(
+        ["fk->", ["field-id", 1], ["field-id", 2]],
+        table1,
+      );
       expect(target.table).toEqual(table2);
       expect(target.field).toEqual(field2);
       expect(target.path).toEqual([field1]);
@@ -302,7 +289,7 @@ describe("Legacy Q_DEPRECATED library", () => {
 
     it("should return field object and table and unit for fk + datetime field", () => {
       const target = Q_DEPRECATED.getFieldTarget(
-        ["datetime-field", ["fk->", 1, 2], "day"],
+        ["datetime-field", ["fk->", ["field-id", 1], ["field-id", 2]], "day"],
         table1,
       );
       expect(target.table).toEqual(table2);
@@ -324,7 +311,9 @@ describe("Legacy Q_DEPRECATED library", () => {
 
 describe("isValidField", () => {
   it("should return true for old-style fk", () => {
-    expect(Q_DEPRECATED.isValidField(["fk->", 1, 2])).toBe(true);
+    expect(
+      Q_DEPRECATED.isValidField(["fk->", ["field-id", 1], ["field-id", 2]]),
+    ).toBe(true);
   });
   it("should return true for new-style fk", () => {
     expect(
@@ -373,7 +362,7 @@ describe("AggregationClause", () => {
     it("should succeed on good clauses", () => {
       expect(A_DEPRECATED.isValid(["metric", 123])).toEqual(true);
       // TODO - actually this should be FALSE because rows is not a valid aggregation type!
-      expect(A_DEPRECATED.isValid(["rows"])).toEqual(true);
+      expect(A_DEPRECATED.isValid(["rows"])).toEqual(true); // deprecated
       expect(A_DEPRECATED.isValid(["sum", 456])).toEqual(true);
     });
   });
@@ -392,7 +381,7 @@ describe("AggregationClause", () => {
     });
 
     it("should succeed on good clauses", () => {
-      expect(A_DEPRECATED.isBareRows(["rows"])).toEqual(true);
+      expect(A_DEPRECATED.isBareRows(["rows"])).toEqual(true); // deprecated
     });
   });
 
@@ -409,7 +398,7 @@ describe("AggregationClause", () => {
     });
 
     it("should succeed on good clauses", () => {
-      expect(A_DEPRECATED.isStandard(["rows"])).toEqual(true);
+      expect(A_DEPRECATED.isStandard(["rows"])).toEqual(true); // deprecated
       expect(A_DEPRECATED.isStandard(["sum", 456])).toEqual(true);
     });
   });
@@ -423,7 +412,7 @@ describe("AggregationClause", () => {
       expect(A_DEPRECATED.isMetric("ab")).toEqual(false);
       expect(A_DEPRECATED.isMetric(["foo", null])).toEqual(false);
       expect(A_DEPRECATED.isMetric(["a", "b", "c"])).toEqual(false);
-      expect(A_DEPRECATED.isMetric(["rows"])).toEqual(false);
+      expect(A_DEPRECATED.isMetric(["rows"])).toEqual(false); // deprecated
       expect(A_DEPRECATED.isMetric(["sum", 456])).toEqual(false);
     });
 
@@ -444,7 +433,7 @@ describe("AggregationClause", () => {
 
   describe("getOperator", () => {
     it("should succeed on good clauses", () => {
-      expect(A_DEPRECATED.getOperator(["rows"])).toEqual("rows");
+      expect(A_DEPRECATED.getOperator(["rows"])).toEqual("rows"); // deprecated
       expect(A_DEPRECATED.getOperator(["sum", 123])).toEqual("sum");
     });
 
@@ -459,7 +448,7 @@ describe("AggregationClause", () => {
     });
 
     it("should be null on clauses w/out a field", () => {
-      expect(A_DEPRECATED.getField(["rows"])).toEqual(null);
+      expect(A_DEPRECATED.getField(["rows"])).toEqual(null); // deprecated
     });
 
     it("should be null on metric clauses", () => {
diff --git a/frontend/test/metabase/lib/query/query.unit.spec.js b/frontend/test/metabase/lib/query/query.unit.spec.js
index bb5c2449aa5ef53f800e0dc8c449073e60e52045..d8f41ebe3d400f21a8e63c9324eb8709c5669bff 100644
--- a/frontend/test/metabase/lib/query/query.unit.spec.js
+++ b/frontend/test/metabase/lib/query/query.unit.spec.js
@@ -2,29 +2,36 @@ import * as Query from "metabase/lib/query/query";
 
 describe("Query", () => {
   describe("isBareRowsAggregation", () => {
-    it("should return true for all bare rows variation", () => {
+    it("should return true for no aggregation", () => {
       expect(Query.isBareRows({})).toBe(true);
+    });
+    it("should return true for no aggregation deprecated form", () => {
       expect(Query.isBareRows({ aggregation: null })).toBe(true); // deprecated
       expect(Query.isBareRows({ aggregation: [] })).toBe(true); // deprecated
     });
     it("should return false for other aggregations", () => {
       expect(Query.isBareRows({ aggregation: [["count"]] })).toBe(false);
+    });
+    it("should return false for other aggregations deprecated form", () => {
       expect(Query.isBareRows({ aggregation: ["count"] })).toBe(false); // deprecated
     });
   });
   describe("getAggregations", () => {
     it("should return an empty list for bare rows", () => {
       expect(Query.getAggregations({})).toEqual([]);
-      expect(Query.getAggregations({ aggregation: [["rows"]] })).toEqual([]);
+    });
+    it("should return an empty list for bare rows for deprecated form", () => {
+      expect(Query.getAggregations({ aggregation: [["rows"]] })).toEqual([]); // deprecated
       expect(Query.getAggregations({ aggregation: ["rows"] })).toEqual([]); // deprecated
     });
     it("should return a single aggregation", () => {
       expect(Query.getAggregations({ aggregation: [["count"]] })).toEqual([
         ["count"],
       ]);
-      expect(Query.getAggregations({ aggregation: ["count"] })).toEqual([
-        ["count"],
-      ]); // deprecated
+    });
+    it("should return a single aggregation for deprecated form", () => {
+      expect(Query.getAggregations({ aggregation: ["count"] })) // deprecated
+        .toEqual([["count"]]);
     });
     it("should return multiple aggregations", () => {
       expect(
@@ -80,9 +87,10 @@ describe("Query", () => {
       expect(Query.removeAggregation({ aggregation: [["count"]] }, 0)).toEqual(
         {},
       );
-      expect(Query.removeAggregation({ aggregation: ["count"] }, 0)).toEqual(
-        {},
-      ); // deprecated
+    });
+    it("should remove the last aggregations for deprecated form", () => {
+      expect(Query.removeAggregation({ aggregation: ["count"] }, 0)) // deprecated
+        .toEqual({});
     });
   });
   describe("clearAggregations", () => {
@@ -93,7 +101,10 @@ describe("Query", () => {
           aggregation: [["count"], ["sum", ["field-id", 1]]],
         }),
       ).toEqual({});
-      expect(Query.clearAggregations({ aggregation: ["count"] })).toEqual({}); // deprecated
+    });
+    it("should remove all aggregations for deprecated form", () => {
+      expect(Query.clearAggregations({ aggregation: ["count"] })) // deprecated
+        .toEqual({});
     });
   });
 
diff --git a/frontend/test/metabase/lib/query_time.unit.spec.js b/frontend/test/metabase/lib/query_time.unit.spec.js
index 8047925f08c64fc3884afb284350115370a7285c..f5eae6ae0080b54ee3a2f966b0471e8ff4ecb724 100644
--- a/frontend/test/metabase/lib/query_time.unit.spec.js
+++ b/frontend/test/metabase/lib/query_time.unit.spec.js
@@ -21,10 +21,10 @@ describe("query_time", () => {
 
     it("supports the legacy DatetimeField format", () => {
       expect(
-        parseFieldBucketing(["datetime-field", ["field-id", 3], "as", "week"]),
+        parseFieldBucketing(["datetime-field", ["field-id", 3], "as", "week"]), // deprecated
       ).toBe("week");
       expect(
-        parseFieldBucketing(["datetime-field", ["field-id", 3], "day"]),
+        parseFieldBucketing(["datetime-field", ["field-id", 3], "as", "day"]), // deprecated
       ).toBe("day");
     });
     it("returns the default unit for FK reference", () => {
@@ -41,19 +41,29 @@ describe("query_time", () => {
   describe("expandTimeIntervalFilter", () => {
     it('translate ["current" "month"] correctly', () => {
       expect(
-        expandTimeIntervalFilter(["time-interval", 100, "current", "month"]),
+        expandTimeIntervalFilter([
+          "time-interval",
+          ["field-id", 100],
+          "current",
+          "month",
+        ]),
       ).toEqual([
         "=",
-        ["datetime-field", 100, "as", "month"],
+        ["datetime-field", ["field-id", 100], "month"],
         ["relative-datetime", "current"],
       ]);
     });
     it('translate [-30, "day"] correctly', () => {
       expect(
-        expandTimeIntervalFilter(["time-interval", 100, -30, "day"]),
+        expandTimeIntervalFilter([
+          "time-interval",
+          ["field-id", 100],
+          -30,
+          "day",
+        ]),
       ).toEqual([
         "between",
-        ["datetime-field", 100, "as", "day"],
+        ["datetime-field", ["field-id", 100], "day"],
         ["relative-datetime", -31, "day"],
         ["relative-datetime", -1, "day"],
       ]);
@@ -283,7 +293,7 @@ describe("query_time", () => {
         );
       });
       // it ('should handle "last week"', () => {
-      //     let [start, end] = computeFilterTimeRange(["time-interval", 1, "last", "week"]);
+      //     let [start, end] = computeFilterTimeRange(["time-interval", ["field-id", 1], "last", "week"]);
       //     expect(start.format("YYYY-MM-DD HH:mm:ss")).toEqual(moment().subtract(1, "week").startOf("week").format("YYYY-MM-DD 00:00:00"));
       //     expect(end.format("YYYY-MM-DD HH:mm:ss")).toEqual(moment().subtract(1, "week").endOf("week")..format("YYYY-MM-DD 23:59:59"));
       // });
diff --git a/frontend/test/metabase/meta/Card.unit.spec.js b/frontend/test/metabase/meta/Card.unit.spec.js
index 7bdd787326e6884227ceda8a40758b0e76828429..c01fa57e0c44d113383d4f2f075aadff8dc71e33 100644
--- a/frontend/test/metabase/meta/Card.unit.spec.js
+++ b/frontend/test/metabase/meta/Card.unit.spec.js
@@ -106,7 +106,7 @@ describe("metabase/meta/Card", () => {
         {
           card_id: 1,
           parameter_id: 4,
-          target: ["dimension", ["fk->", 4, 5]],
+          target: ["dimension", ["fk->", ["field-id", 4], ["field-id", 5]]],
         },
       ];
       it("should return question URL with no parameters", () => {
@@ -215,7 +215,15 @@ describe("metabase/meta/Card", () => {
             ["dataset_query", "query", "filter"],
             [
               "and",
-              ["=", ["datetime-field", ["fk->", 4, 5], "month"], "2017-05-01"],
+              [
+                "=",
+                [
+                  "datetime-field",
+                  ["fk->", ["field-id", 4], ["field-id", 5]],
+                  "month",
+                ],
+                "2017-05-01",
+              ],
             ],
           ),
         });
diff --git a/frontend/test/metabase/modes/components/actions/CountByTimeAction.unit.spec.js b/frontend/test/metabase/modes/components/actions/CountByTimeAction.unit.spec.js
index 160ecebabc37e4a89da32aba66d51245f9462912..bbfda65f897ebbdfce2dfd621b185659f071f255 100644
--- a/frontend/test/metabase/modes/components/actions/CountByTimeAction.unit.spec.js
+++ b/frontend/test/metabase/modes/components/actions/CountByTimeAction.unit.spec.js
@@ -21,12 +21,7 @@ describe("CountByTimeAction", () => {
       "source-table": ORDERS_TABLE_ID,
       aggregation: [["count"]],
       breakout: [
-        [
-          "datetime-field",
-          ["field-id", ORDERS_CREATED_DATE_FIELD_ID],
-          "as",
-          "day",
-        ],
+        ["datetime-field", ["field-id", ORDERS_CREATED_DATE_FIELD_ID], "day"],
       ],
     });
     expect(newCard.display).toEqual("bar");
diff --git a/frontend/test/metabase/modes/components/drill/UnderlyingRecordsDrill.unit.spec.js b/frontend/test/metabase/modes/components/drill/UnderlyingRecordsDrill.unit.spec.js
index 039dfead11e2b70ea58b3084369d639c8439870f..b3b74fd4aa32ddfcf27384c40b51bd1d062cc071 100644
--- a/frontend/test/metabase/modes/components/drill/UnderlyingRecordsDrill.unit.spec.js
+++ b/frontend/test/metabase/modes/components/drill/UnderlyingRecordsDrill.unit.spec.js
@@ -21,12 +21,7 @@ function getActionPropsForTimeseriesClick(unit, value) {
         "source-table": ORDERS_TABLE_ID,
         aggregation: [["count"]],
         breakout: [
-          [
-            "datetime-field",
-            ["field-id", ORDERS_CREATED_DATE_FIELD_ID],
-            "as",
-            unit,
-          ],
+          ["datetime-field", ["field-id", ORDERS_CREATED_DATE_FIELD_ID], unit],
         ],
       })
       .question(),
@@ -57,12 +52,7 @@ describe("UnderlyingRecordsDrill", () => {
       "source-table": ORDERS_TABLE_ID,
       filter: [
         "=",
-        [
-          "datetime-field",
-          ["field-id", ORDERS_CREATED_DATE_FIELD_ID],
-          "as",
-          "month",
-        ],
+        ["datetime-field", ["field-id", ORDERS_CREATED_DATE_FIELD_ID], "month"],
         value,
       ],
     });
@@ -93,7 +83,6 @@ describe("UnderlyingRecordsDrill", () => {
         [
           "datetime-field",
           ["field-id", ORDERS_CREATED_DATE_FIELD_ID],
-          "as",
           "day-of-week",
         ],
         null,
diff --git a/frontend/test/metabase/modes/components/drill/ZoomDrill.unit.spec.js b/frontend/test/metabase/modes/components/drill/ZoomDrill.unit.spec.js
index 46156d5c1dda8b587275b3a104446fb3475dab26..89c60ac92c77c4de48e297dc6296ab568bc24426 100644
--- a/frontend/test/metabase/modes/components/drill/ZoomDrill.unit.spec.js
+++ b/frontend/test/metabase/modes/components/drill/ZoomDrill.unit.spec.js
@@ -27,7 +27,6 @@ describe("ZoomDrill", () => {
             [
               "datetime-field",
               ["field-id", ORDERS_CREATED_DATE_FIELD_ID],
-              "as",
               "month",
             ],
           ],
@@ -49,21 +48,11 @@ describe("ZoomDrill", () => {
       aggregation: [["count"]],
       filter: [
         "=",
-        [
-          "datetime-field",
-          ["field-id", ORDERS_CREATED_DATE_FIELD_ID],
-          "as",
-          "month",
-        ],
+        ["datetime-field", ["field-id", ORDERS_CREATED_DATE_FIELD_ID], "month"],
         clickedDateTimeValue.value,
       ],
       breakout: [
-        [
-          "datetime-field",
-          ["field-id", ORDERS_CREATED_DATE_FIELD_ID],
-          // "as",
-          "week",
-        ],
+        ["datetime-field", ["field-id", ORDERS_CREATED_DATE_FIELD_ID], "week"],
       ],
     });
     expect(newCard.display).toEqual("line");
diff --git a/frontend/test/metabase/modes/lib/actions.unit.spec.js b/frontend/test/metabase/modes/lib/actions.unit.spec.js
index 26c7d1862def894cb6df4808373589e2af6bc27a..0e2cecadd441abe55f302f9e77e5d0b87e61a6f1 100644
--- a/frontend/test/metabase/modes/lib/actions.unit.spec.js
+++ b/frontend/test/metabase/modes/lib/actions.unit.spec.js
@@ -22,7 +22,7 @@ describe("actions", () => {
       expect(newCard.dataset_query.query).toEqual({
         filter: [
           "=",
-          ["datetime-field", ["field-id", 123], "as", "day"],
+          ["datetime-field", ["field-id", 123], "day"],
           "2018-04-27T00:00:00+02:00",
         ],
       });
diff --git a/frontend/test/metabase/public/public.e2e.spec.js b/frontend/test/metabase/public/public.e2e.spec.js
index 1ff48a271930bc78191f6d281b2f02d126bcb48a..c856ba033649adae61ea42cbf95bd6da50f5350d 100644
--- a/frontend/test/metabase/public/public.e2e.spec.js
+++ b/frontend/test/metabase/public/public.e2e.spec.js
@@ -55,7 +55,7 @@ import Select from "metabase/components/Select";
 import RunButton from "metabase/query_builder/components/RunButton";
 import Scalar from "metabase/visualizations/visualizations/Scalar";
 import ParameterFieldWidget from "metabase/parameters/components/widgets/ParameterFieldWidget";
-import TextWidget from "metabase/parameters/components/widgets/TextWidget.jsx";
+import TextWidget from "metabase/parameters/components/widgets/TextWidget";
 import SaveQuestionModal from "metabase/containers/SaveQuestionModal";
 import SharingPane from "metabase/public/components/widgets/SharingPane";
 import { EmbedTitle } from "metabase/public/components/widgets/EmbedModalContent";
@@ -414,7 +414,7 @@ describe("public/embedded", () => {
           type: "query",
           query: {
             "source-table": PEOPLE_TABLE_ID,
-            aggregation: ["count"],
+            aggregation: [["count"]],
           },
         },
       });
diff --git a/frontend/test/metabase/query_builder/components/FieldName.unit.spec.js b/frontend/test/metabase/query_builder/components/FieldName.unit.spec.js
index d4883e9e116bae5fcf139d4b5a99dd7a5847153f..e067a543eea2e8dec66311de45f24bbb431c541a 100644
--- a/frontend/test/metabase/query_builder/components/FieldName.unit.spec.js
+++ b/frontend/test/metabase/query_builder/components/FieldName.unit.spec.js
@@ -9,7 +9,7 @@ import {
   PRODUCT_CATEGORY_FIELD_ID,
 } from "__support__/sample_dataset_fixture";
 
-import FieldName from "metabase/query_builder/components/FieldName.jsx";
+import FieldName from "metabase/query_builder/components/FieldName";
 
 describe("FieldName", () => {
   it("should render regular field correctly", () => {
@@ -60,7 +60,10 @@ describe("FieldName", () => {
   it("should render nested fk field correctly", () => {
     pending();
     const fieldName = mount(
-      <FieldName field={["fk->", 3, 2]} tableMetadata={ORDERS_TABLE_ID} />,
+      <FieldName
+        field={["fk->", ["field-id", 3], ["field-id", 2]]}
+        tableMetadata={ORDERS_TABLE_ID}
+      />,
     );
     expect(fieldName.text()).toEqual("BarFoo: Baz");
   });
diff --git a/frontend/test/metabase/reference/databases.e2e.spec.js b/frontend/test/metabase/reference/databases.e2e.spec.js
index 9ed63b79dde8f0c91b0f80582be163049847f9b4..b2f7cb72d0b050033c7695d0eacc6ac4f3732bd9 100644
--- a/frontend/test/metabase/reference/databases.e2e.spec.js
+++ b/frontend/test/metabase/reference/databases.e2e.spec.js
@@ -22,10 +22,10 @@ import FieldListContainer from "metabase/reference/databases/FieldListContainer"
 import FieldDetailContainer from "metabase/reference/databases/FieldDetailContainer";
 
 import DatabaseList from "metabase/reference/databases/DatabaseList";
-import List from "metabase/components/List.jsx";
-import ListItem from "metabase/components/ListItem.jsx";
-import ReferenceHeader from "metabase/reference/components/ReferenceHeader.jsx";
-import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState.jsx";
+import List from "metabase/components/List";
+import ListItem from "metabase/components/ListItem";
+import ReferenceHeader from "metabase/reference/components/ReferenceHeader";
+import AdminAwareEmptyState from "metabase/components/AdminAwareEmptyState";
 import UsefulQuestions from "metabase/reference/components/UsefulQuestions";
 import QueryButton from "metabase/components/QueryButton";
 import { INITIALIZE_QB, QUERY_COMPLETED } from "metabase/query_builder/actions";
@@ -39,7 +39,7 @@ describe("The Reference Section", () => {
     dataset_query: {
       database: 1,
       type: "query",
-      query: { "source-table": 1, aggregation: ["count"] },
+      query: { "source-table": 1, aggregation: [["count"]] },
     },
     visualization_settings: {},
   };
diff --git a/frontend/test/metabase/reference/guide.e2e.spec.js b/frontend/test/metabase/reference/guide.e2e.spec.js
index 78e49d80143bec89dae935186abf8631aa0fc9c0..002d7fc01da241c1d15b9165d2b81aec6076af8c 100644
--- a/frontend/test/metabase/reference/guide.e2e.spec.js
+++ b/frontend/test/metabase/reference/guide.e2e.spec.js
@@ -41,7 +41,7 @@ describe("The Reference Section", () => {
     description: "I did it!",
     table_id: 1,
     show_in_getting_started: true,
-    definition: { database: 1, query: { aggregation: ["count"] } },
+    definition: { database: 1, query: { aggregation: [["count"]] } },
   };
 
   const anotherMetricDef = {
@@ -49,7 +49,7 @@ describe("The Reference Section", () => {
     description: "I did it again!",
     table_id: 1,
     show_in_getting_started: true,
-    definition: { database: 1, query: { aggregation: ["count"] } },
+    definition: { database: 1, query: { aggregation: [["count"]] } },
   };
 
   // Scaffolding
diff --git a/frontend/test/metabase/reference/segments.e2e.spec.js b/frontend/test/metabase/reference/segments.e2e.spec.js
index 94e15fe1783a081279a25492aec0e470982899f9..ef8451ccbe861efa8f9c28e5e8750ab5b0ac8543 100644
--- a/frontend/test/metabase/reference/segments.e2e.spec.js
+++ b/frontend/test/metabase/reference/segments.e2e.spec.js
@@ -56,7 +56,7 @@ describe("The Reference Section", () => {
       type: "query",
       query: {
         "source-table": 1,
-        aggregation: ["count"],
+        aggregation: [["count"]],
         filter: ["segment", 1],
       },
     },
diff --git a/frontend/test/metabase/reference/utils.unit.spec.js b/frontend/test/metabase/reference/utils.unit.spec.js
index 4f81cedb4f6e213a8be498083b1b0b745f7f4c1c..e34559b829dbd00e83963980f4c68c5ccd211dbc 100644
--- a/frontend/test/metabase/reference/utils.unit.spec.js
+++ b/frontend/test/metabase/reference/utils.unit.spec.js
@@ -147,7 +147,7 @@ describe("Reference utils.js", () => {
         getNewQuestion({
           database: 3,
           table: 4,
-          aggregation: ["count"],
+          aggregation: [["count"]],
         }),
       );
     });
@@ -183,7 +183,7 @@ describe("Reference utils.js", () => {
           table: 4,
           display: "bar",
           breakout: [["field-id", 5]],
-          aggregation: ["count"],
+          aggregation: [["count"]],
         }),
       );
     });
@@ -203,7 +203,7 @@ describe("Reference utils.js", () => {
           table: 4,
           display: "pie",
           breakout: [["field-id", 5]],
-          aggregation: ["count"],
+          aggregation: [["count"]],
         }),
       );
     });
@@ -217,7 +217,7 @@ describe("Reference utils.js", () => {
 
       expect(question).toEqual(
         getNewQuestion({
-          aggregation: ["metric", 3],
+          aggregation: [["metric", 3]],
         }),
       );
     });
@@ -232,7 +232,7 @@ describe("Reference utils.js", () => {
 
       expect(question).toEqual(
         getNewQuestion({
-          aggregation: ["metric", 3],
+          aggregation: [["metric", 3]],
           breakout: [["field-id", 4]],
         }),
       );
@@ -249,7 +249,7 @@ describe("Reference utils.js", () => {
         getNewQuestion({
           database: 2,
           table: 3,
-          filter: ["and", ["segment", 4]],
+          filter: ["segment", 4],
         }),
       );
     });
@@ -266,8 +266,8 @@ describe("Reference utils.js", () => {
         getNewQuestion({
           database: 2,
           table: 3,
-          aggregation: ["count"],
-          filter: ["and", ["segment", 4]],
+          aggregation: [["count"]],
+          filter: ["segment", 4],
         }),
       );
     });
diff --git a/frontend/test/metabase/visualizations/components/LegendVertical.unit.spec.js b/frontend/test/metabase/visualizations/components/LegendVertical.unit.spec.js
index b7363ef7a3ad6e86c166f5ea47e3278c8068079c..34bc40a06622abf7feee57db039d5f82b0b6216e 100644
--- a/frontend/test/metabase/visualizations/components/LegendVertical.unit.spec.js
+++ b/frontend/test/metabase/visualizations/components/LegendVertical.unit.spec.js
@@ -1,5 +1,5 @@
 import React from "react";
-import LegendVertical from "metabase/visualizations/components/LegendVertical.jsx";
+import LegendVertical from "metabase/visualizations/components/LegendVertical";
 import { mount } from "enzyme";
 
 describe("LegendVertical", () => {
diff --git a/frontend/test/metabase/visualizations/components/LineAreaBarChart.unit.spec.js b/frontend/test/metabase/visualizations/components/LineAreaBarChart.unit.spec.js
index 00476766980ae4c68652ff179eb618130b90aa7c..ecc7ee867fa288e6661f20f60ee667ffda9a99cc 100644
--- a/frontend/test/metabase/visualizations/components/LineAreaBarChart.unit.spec.js
+++ b/frontend/test/metabase/visualizations/components/LineAreaBarChart.unit.spec.js
@@ -3,7 +3,7 @@
 // HACK: Needed because of conflicts caused by circular dependencies
 import "metabase/visualizations/components/Visualization";
 
-import LineAreaBarChart from "metabase/visualizations/components/LineAreaBarChart";
+import LineAreaBarChart from "metabase/visualizations/components/LineAreaBarChart.jsx";
 
 const millisecondCard = {
   card: {
diff --git a/frontend/test/metabase/visualizations/components/Visualization.unit.spec.js b/frontend/test/metabase/visualizations/components/Visualization.unit.spec.js
index b75c5d35a709e11d630e9c49cc3fb375eabe8eca..f9f455b992ee9b927cc884816d4fb042fa03e3e2 100644
--- a/frontend/test/metabase/visualizations/components/Visualization.unit.spec.js
+++ b/frontend/test/metabase/visualizations/components/Visualization.unit.spec.js
@@ -8,7 +8,7 @@ import {
   cleanupFixture,
 } from "../__support__/visualizations";
 
-import colors from "metabase/lib/colors";
+import { color } from "metabase/lib/colors";
 import Visualization from "metabase/visualizations/components/Visualization";
 
 describe("Visualization", () => {
@@ -61,8 +61,8 @@ describe("Visualization", () => {
           },
         ]);
         expect(getBarColors()).toEqual([
-          colors.brand, // "count"
-          colors.brand, // "count"
+          color("brand"), // "count"
+          color("brand"), // "count"
         ]);
       });
     });
@@ -82,10 +82,10 @@ describe("Visualization", () => {
           },
         ]);
         expect(getBarColors()).toEqual([
-          colors.brand, // "count"
-          colors.brand, // "count"
-          colors.accent1, // "sum"
-          colors.accent1, // "sum"
+          color("brand"), // "count"
+          color("brand"), // "count"
+          color("accent1"), // "sum"
+          color("accent1"), // "sum"
         ]);
       });
     });
@@ -110,10 +110,10 @@ describe("Visualization", () => {
           },
         ]);
         expect(getBarColors()).toEqual([
-          colors.accent1, // "a"
-          colors.accent1, // "a"
-          colors.accent2, // "b"
-          colors.accent2, // "b"
+          color("accent1"), // "a"
+          color("accent1"), // "a"
+          color("accent2"), // "b"
+          color("accent2"), // "b"
         ]);
       });
     });
@@ -142,10 +142,10 @@ describe("Visualization", () => {
           },
         ]);
         expect(getBarColors()).toEqual([
-          colors.brand, // "count"
-          colors.brand, // "count"
-          colors.accent2, // "Card2"
-          colors.accent2, // "Card2"
+          color("brand"), // "count"
+          color("brand"), // "count"
+          color("accent2"), // "Card2"
+          color("accent2"), // "Card2"
         ]);
       });
     });
diff --git a/frontend/test/metabase/visualizations/lib/utils.unit.spec.js b/frontend/test/metabase/visualizations/lib/utils.unit.spec.js
index f74e730587eab1c774849adb240071fa9bb7cb2d..dbcb4e06eabcf5996c53de11bd19ee8973af9b48 100644
--- a/frontend/test/metabase/visualizations/lib/utils.unit.spec.js
+++ b/frontend/test/metabase/visualizations/lib/utils.unit.spec.js
@@ -32,7 +32,10 @@ const breakoutMultiseriesQuery = {
   ...baseQuery,
   query: {
     ...baseQuery.query,
-    breakout: [...baseQuery.query.breakout, ["fk->", 1, 10]],
+    breakout: [
+      ...baseQuery.query.breakout,
+      ["fk->", ["field-id", 1], ["field-id", 10]],
+    ],
   },
 };
 const derivedBreakoutMultiseriesQuery = {
diff --git a/modules/drivers/druid/src/metabase/driver/druid/query_processor.clj b/modules/drivers/druid/src/metabase/driver/druid/query_processor.clj
index d010c2e61533cf4bf7fd0219fab1e0e94aee2fdf..043e1dc44575333c08cdf9083dff226f985d7534 100644
--- a/modules/drivers/druid/src/metabase/driver/druid/query_processor.clj
+++ b/modules/drivers/druid/src/metabase/driver/druid/query_processor.clj
@@ -84,7 +84,8 @@
     :distinct___count
 
     (= ag-type :aggregation-options)
-    (recur (second ag))
+    (let [[_ wrapped-ag options] ag]
+      (or (:name options) (recur wrapped-ag)))
 
     ag-type
     ag-type
@@ -514,13 +515,23 @@
 
 (defn- ag:distinct
   [field output-name]
-  (if (isa? (:base-type field) :type/DruidHyperUnique)
+  (cond
+    (mbql.u/is-clause? #{:+} field)
+    {:type       :cardinality
+     :name       output-name
+     :fieldNames (mapv ->rvalue (rest field))
+     :byRow      true
+     :round      true}
+    (isa? (:base-type field) :type/DruidHyperUnique)
     {:type      :hyperUnique
      :name      output-name
      :fieldName (->rvalue field)}
+    :else
     {:type       :cardinality
      :name       output-name
-     :fieldNames [(->rvalue field)]}))
+     :fieldNames [(->rvalue field)]
+     :byRow      true
+     :round      true}))
 
 (defn- ag:count
   ([output-name]
@@ -888,6 +899,9 @@
                             :distinct
                             :distinct___count
 
+                            [:aggregation-options _ (options :guard :name)]
+                            (:name options)
+
                             [:aggregation-options wrapped-ag _]
                             (recur wrapped-ag)
 
@@ -1007,7 +1021,8 @@
 (defmethod handle-limit ::groupBy
   [_ {limit :limit} updated-query]
   (if-not limit
-    updated-query
+    (-> updated-query
+        (assoc-in [:query :limitSpec :type]  :default))
     (-> updated-query
         (assoc-in [:query :limitSpec :type]  :default)
         (assoc-in [:query :limitSpec :limit] limit))))
diff --git a/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj b/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj
index 7eb078516f614cec7edce40cb2c92bbad68d1831..5cda190572e9b07a9b9f279a8f4623224be9fd58 100644
--- a/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj
+++ b/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj
@@ -37,12 +37,83 @@
                  :metric           {:type :alphaNumeric}
                  :aggregations
                  [{:type       :filtered
-                   :filter
-                   {:type  :not
-                    :field {:type :selector, :dimension "id", :value nil}}
+                   :filter     {:type  :not
+                                :field {:type :selector, :dimension "id", :value nil}}
                    :aggregator {:type :count, :name "__count_0"}}]}
    :query-type  ::druid.qp/topN
    :mbql?       true}
   (query->native
    {:aggregation [[:* [:count $id] 10]]
     :breakout    [$venue_price]}))
+
+(datasets/expect-with-driver :druid
+  {:projections [:venue_category_name :user_name :__count_0]
+   :query       {:queryType    :groupBy
+                 :granularity  :all
+                 :dataSource   "checkins"
+                 :dimensions   ["venue_category_name", "user_name"]
+                 :context      {:timeout 60000, :queryId "<Query ID>"}
+                 :intervals    ["1900-01-01/2100-01-01"]
+                 :aggregations [{:type       :cardinality
+                                 :name       "__count_0"
+                                 :fieldNames ["venue_name"]
+                                 :byRow      true
+                                 :round      true}]
+                 :limitSpec    {:type    :default
+                                :columns [{:dimension "__count_0", :direction :descending}
+                                          {:dimension "venue_category_name", :direction :ascending}
+                                          {:dimension "user_name", :direction :ascending}]}}
+   :query-type ::druid.qp/groupBy
+   :mbql?      true}
+  (query->native
+   {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
+    :breakout    [$venue_category_name $user_name]
+    :order-by    [[:desc [:aggregation 0]] [:asc $checkins.venue_category_name]]}))
+
+(datasets/expect-with-driver :druid
+  {:projections [:venue_category_name :user_name :__count_0]
+   :query       {:queryType    :groupBy
+                 :granularity  :all
+                 :dataSource   "checkins"
+                 :dimensions   ["venue_category_name", "user_name"]
+                 :context      {:timeout 60000, :queryId "<Query ID>"}
+                 :intervals    ["1900-01-01/2100-01-01"]
+                 :aggregations [{:type       :cardinality
+                                 :name       "__count_0"
+                                 :fieldNames ["venue_name"]
+                                 :byRow      true
+                                 :round      true}]
+                 :limitSpec    {:type    :default
+                                :columns [{:dimension "__count_0", :direction :descending}
+                                          {:dimension "venue_category_name", :direction :ascending}
+                                          {:dimension "user_name", :direction :ascending}]
+                                :limit   5}}
+   :query-type  ::druid.qp/groupBy
+   :mbql?       true}
+  (query->native
+   {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
+    :breakout    [$venue_category_name $user_name]
+    :order-by    [[:desc [:aggregation 0]] [:asc $checkins.venue_category_name]]
+    :limit       5}))
+
+(datasets/expect-with-driver :druid
+  {:projections [:venue_category_name :__count_0]
+   :query       {:queryType    :topN
+                 :threshold    1000
+                 :granularity  :all
+                 :dataSource   "checkins"
+                 :dimension    "venue_category_name"
+                 :context      {:timeout 60000, :queryId "<Query ID>"}
+                 :intervals    ["1900-01-01/2100-01-01"]
+                 :metric       "__count_0"
+                 :aggregations [{:type       :cardinality
+                                 :name       "__count_0"
+                                 :fieldNames ["venue_name"]
+                                 :byRow      true
+                                 :round      true}]}
+   :query-type  ::druid.qp/topN
+   :mbql?       true}
+  (query->native
+   {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
+    :breakout    [$venue_category_name]
+    :order-by    [[:desc [:aggregation 0]] [:asc $checkins.venue_category_name]]}))
diff --git a/modules/drivers/druid/test/metabase/driver/druid_test.clj b/modules/drivers/druid/test/metabase/driver/druid_test.clj
index 609023cfb3970ff2ec01d517c02cbad21085501c..8cd232eef70da4e5dfb1e4efb26bbed2f536124b 100644
--- a/modules/drivers/druid/test/metabase/driver/druid_test.clj
+++ b/modules/drivers/druid/test/metabase/driver/druid_test.clj
@@ -27,6 +27,14 @@
             [toucan.util.test :as tt]))
 
 ;;; table-rows-sample
+(defn table-rows-sample []
+  (->> (metadata-queries/table-rows-sample (Table (data/id :checkins))
+         [(Field (data/id :checkins :id))
+          (Field (data/id :checkins :venue_name))
+          (Field (data/id :checkins :timestamp))])
+       (sort-by first)
+       (take 5)))
+
 (datasets/expect-with-driver :druid
   ;; druid returns a timestamp along with the query, but that shouldn't really matter here :D
   [["1"    "The Misfit Restaurant + Bar" #inst "2014-04-07T07:00:00.000Z"]
@@ -34,12 +42,7 @@
    ["100"  "PizzaHacker"                 #inst "2014-07-26T07:00:00.000Z"]
    ["1000" "Tito's Tacos"                #inst "2014-06-03T07:00:00.000Z"]
    ["101"  "Golden Road Brewing"         #inst "2015-09-04T07:00:00.000Z"]]
-  (->> (metadata-queries/table-rows-sample (Table (data/id :checkins))
-         [(Field (data/id :checkins :id))
-          (Field (data/id :checkins :venue_name))
-          (Field (data/id :checkins :timestamp))])
-       (sort-by first)
-       (take 5)))
+  (table-rows-sample))
 
 (datasets/expect-with-driver :druid
   ;; druid returns a timestamp along with the query, but that shouldn't really matter here :D
@@ -49,12 +52,7 @@
    ["1000" "Tito's Tacos"                #inst "2014-06-03T00:00:00.000-07:00"]
    ["101"  "Golden Road Brewing"         #inst "2015-09-04T00:00:00.000-07:00"]]
   (tu/with-temporary-setting-values [report-timezone "America/Los_Angeles"]
-    (->> (metadata-queries/table-rows-sample (Table (data/id :checkins))
-           [(Field (data/id :checkins :id))
-            (Field (data/id :checkins :venue_name))
-            (Field (data/id :checkins :timestamp))])
-         (sort-by first)
-         (take 5))))
+    (table-rows-sample)))
 
 (datasets/expect-with-driver :druid
   ;; druid returns a timestamp along with the query, but that shouldn't really matter here :D
@@ -64,12 +62,7 @@
    ["1000" "Tito's Tacos"                #inst "2014-06-03T02:00:00.000-05:00"]
    ["101"  "Golden Road Brewing"         #inst "2015-09-04T02:00:00.000-05:00"]]
   (tu.tz/with-jvm-tz (time/time-zone-for-id "America/Chicago")
-    (->> (metadata-queries/table-rows-sample (Table (data/id :checkins))
-           [(Field (data/id :checkins :id))
-            (Field (data/id :checkins :venue_name))
-            (Field (data/id :checkins :timestamp))])
-         (sort-by first)
-         (take 5))))
+    (table-rows-sample)))
 
 (def ^:private ^String native-query-1
   (json/generate-string
@@ -135,14 +128,14 @@
 ;; make sure we can run a native :timeseries query. This was throwing an Exception -- see #3409
 (def ^:private ^String native-query-2
   (json/generate-string
-    {:intervals    ["1900-01-01/2100-01-01"]
-     :granularity  {:type     :period
-                    :period   :P1M
-                    :timeZone :UTC}
-     :queryType    :timeseries
-     :dataSource   :checkins
-     :aggregations [{:type :count
-                     :name :count}]}))
+   {:intervals    ["1900-01-01/2100-01-01"]
+    :granularity  {:type     :period
+                   :period   :P1M
+                   :timeZone :UTC}
+    :queryType    :timeseries
+    :dataSource   :checkins
+    :aggregations [{:type :count
+                    :name :count}]}))
 
 (datasets/expect-with-driver :druid
   :completed
@@ -340,6 +333,15 @@
       {:aggregation [[:aggregation-options [:- [:sum $venue_price] 41] {:name "Sum-41"}]]
        :breakout    [$venue_price]})))
 
+;; distinct count of two dimensions
+(datasets/expect-with-driver :druid
+   {:rows [[98]]
+    :columns ["count"]}
+   (qp.test/rows+column-names
+    (druid-query
+     {:aggregation [[:distinct [:+  $checkins.venue_category_name
+                                    $checkins.venue_name]]]})))
+
 ;; check that we can handle METRICS (ick) inside expression aggregation clauses
 (datasets/expect-with-driver :druid
   [["2" 1231.0]
@@ -349,12 +351,9 @@
     (tt/with-temp Metric [metric {:definition {:aggregation [:sum [:field-id (data/id :checkins :venue_price)]]
                                                :filter      [:> [:field-id (data/id :checkins :venue_price)] 1]}}]
       (qp.test/rows
-        (qp/process-query
-          {:database (data/id)
-           :type     :query
-           :query    {:source-table (data/id :checkins)
-                      :aggregation  [:+ [:metric (u/get-id metric)] 1]
-                      :breakout     [[:field-id (data/id :checkins :venue_price)]]}})))))
+        (data/run-mbql-query checkins
+          {:aggregation [:+ [:metric (u/get-id metric)] 1]
+           :breakout    [$venue_price]})))))
 
 (expect
   com.jcraft.jsch.JSchException
@@ -430,12 +429,33 @@
            "Kinaree Thai Bistro"
            "1"]]}
   (tqpt/with-flattened-dbdef
-    (let [results (qp/process-query
-                    {:database (data/id)
-                     :type     :query
-                     :query    {:source-table (data/id :checkins)
-                                :limit        1}})]
+    (let [results (data/run-mbql-query checkins
+                    {:limit 1})]
       (assert (= (:status results) :completed)
         (u/pprint-to-str 'red results))
       {:cols (->> results :data :cols (map :name))
        :rows (-> results :data :rows)})))
+
+(datasets/expect-with-driver :druid
+  [["Bar" "Felipinho Asklepios"      8]
+   ["Bar" "Spiros Teofil"            8]
+   ["Japanese" "Felipinho Asklepios" 7]
+   ["Japanese" "Frans Hevel"         7]
+   ["Mexican" "Shad Ferdynand"       7]]
+  (druid-query-returning-rows
+    {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
+     :breakout    [$venue_category_name $user_name]
+     :order-by    [[:desc [:aggregation 0]] [:asc $checkins.venue_category_name]]
+     :limit       5}))
+
+(datasets/expect-with-driver :druid
+  [["American" "Rüstem Hebel"    1]
+   ["Artisan"  "Broen Olujimi"   1]
+   ["Artisan"  "Conchúr Tihomir" 1]
+   ["Artisan"  "Dwight Gresham"  1]
+   ["Artisan"  "Plato Yeshua"    1]]
+  (druid-query-returning-rows
+    {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
+     :breakout   [$venue_category_name $user_name]
+     :order-by   [[:asc [:aggregation 0]] [:asc $checkins.venue_category_name]]
+     :limit      5}))
diff --git a/modules/drivers/druid/test/metabase/test/data/druid.clj b/modules/drivers/druid/test/metabase/test/data/druid.clj
index 177b269d2b4caa22bf5e1c5a7728470aaf02852e..c25088151e577671a61238e21f930470e65ee81b 100644
--- a/modules/drivers/druid/test/metabase/test/data/druid.clj
+++ b/modules/drivers/druid/test/metabase/test/data/druid.clj
@@ -73,10 +73,13 @@
                                                                                    "user_name"
                                                                                    "user_password"
                                                                                    "venue_category_name"
-                                                                                   "venue_latitude"
-                                                                                   "venue_longitude"
+                                                                                   {:name "venue_latitude"
+                                                                                    :type "double"}
+                                                                                   {:name "venue_longitude"
+                                                                                    :type "double"}
                                                                                    "venue_name"
-                                                                                   "venue_price"]}}}
+                                                                                   {:name "venue_price"
+                                                                                    :type "float"}]}}}
                        :metricsSpec     [{:type :count
                                           :name :count}]
                        :granularitySpec {:type               :uniform
diff --git a/package.json b/package.json
index b22dea9f8ce86ad1ebff03481762c3491c75a0f6..e9a309c9d25a114d5add422edd87285f61ded220 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
     "inflection": "^1.7.1",
     "isomorphic-fetch": "^2.2.1",
     "js-cookie": "^2.1.2",
+    "json-bigint": "^0.3.0",
     "jsrsasign": "^7.1.0",
     "leaflet": "^1.2.0",
     "leaflet-draw": "^0.4.9",
diff --git a/project.clj b/project.clj
index 9d96179368e0116227966f227f502fdfe72021a0..799a9d165eb9b7f18bb6a4eac3f4e4942944e6d1 100644
--- a/project.clj
+++ b/project.clj
@@ -131,10 +131,10 @@
   :manifest
   {"Liquibase-Package"
    #=(eval
-      (str "liquibase.change,liquibase.changelog,liquibase.database,liquibase.parser,liquibase.precondition,"
-           "liquibase.datatype,liquibase.serializer,liquibase.sqlgenerator,liquibase.executor,"
-           "liquibase.snapshot,liquibase.logging,liquibase.diff,liquibase.structure,"
-           "liquibase.structurecompare,liquibase.lockservice,liquibase.sdk,liquibase.ext"))}
+       (str "liquibase.change,liquibase.changelog,liquibase.database,liquibase.parser,liquibase.precondition,"
+            "liquibase.datatype,liquibase.serializer,liquibase.sqlgenerator,liquibase.executor,"
+            "liquibase.snapshot,liquibase.logging,liquibase.diff,liquibase.structure,"
+            "liquibase.structurecompare,liquibase.lockservice,liquibase.sdk,liquibase.ext"))}
 
   :jvm-opts
   ["-XX:+IgnoreUnrecognizedVMOptions"                                 ; ignore things not recognized for our Java version instead of refusing to start
@@ -257,7 +257,7 @@
                            ;; disabled (yet)
                            ;;
                            ;; For example see https://github.com/jonase/eastwood/issues/193
-                           ;
+                                                                      ;
                            ;; It's still useful to re-enable them and run them every once in a while because they catch
                            ;; a lot of actual errors too. Keep an eye on the issue above and re-enable them if we can
                            ;; get them to work
diff --git a/src/metabase/automagic_dashboards/core.clj b/src/metabase/automagic_dashboards/core.clj
index e4371f36aaf4ee96aaa7a82f46fa6eebfca24bef..857312d7dcbcf0e47fdd5f91650250133fba596f 100644
--- a/src/metabase/automagic_dashboards/core.clj
+++ b/src/metabase/automagic_dashboards/core.clj
@@ -316,8 +316,13 @@
       reference)))
 
 (defmethod ->reference [:string (type Field)]
-  [_ {:keys [display_name full-name]}]
-  (or full-name display_name))
+  [_ {:keys [display_name full-name link table_id]}]
+  (cond
+    full-name full-name
+    link      (format "%s → %s"
+                      (-> link Field :display_name (str/replace #"(?i)\sid$" ""))
+                      display_name)
+    :else     display_name))
 
 (defmethod ->reference [:string (type Table)]
   [_ {:keys [display_name full-name]}]
diff --git a/src/metabase/models/setting.clj b/src/metabase/models/setting.clj
index f0172c5159dd81062721d9fb50a0f6743c58106a..aaf7582a6b00f7184392d57a46cb0ea7da742f4c 100644
--- a/src/metabase/models/setting.clj
+++ b/src/metabase/models/setting.clj
@@ -32,6 +32,7 @@
   (:require [cheshire.core :as json]
             [clojure
              [core :as core]
+             [data :as data]
              [string :as str]]
             [clojure.data.csv :as csv]
             [clojure.tools.logging :as log]
@@ -82,7 +83,12 @@
    :tag         (s/maybe Class)  ; type annotation, e.g. ^String, to be applied. Defaults to tag based on :type
    :sensitive?  s/Bool           ; is this sensitive (never show in plaintext), like a password? (default: false)
    :internal?   s/Bool           ; should the API never return this setting? (default: false)
-   :cache?      s/Bool})         ; should the getter always fetch this value "fresh" from the DB? (default: false)
+   :cache?      s/Bool           ; should the getter always fetch this value "fresh" from the DB? (default: false)
+
+  ;; called whenever setting value changes, whether from update-setting! or a cache refresh. used to handle cases
+  ;; where a change to the cache necessitates a change to some value outside the cache, like when a change the
+  ;; `:site-locale` setting requires a call to `java.util.Locale/setDefault`
+  :on-change   (s/maybe clojure.lang.IFn)})
 
 
 (defonce ^:private registered-settings
@@ -98,6 +104,18 @@
                   (tru "Setting {0} does not exist.\nFound: {1}" k (sort (keys @registered-settings)))))))))
 
 
+(defn- call-on-change
+  "Cache watcher that applies `:on-change` callback for all settings that have changed."
+  [_key _ref old new]
+  (let [rs      @registered-settings
+        [d1 d2] (data/diff old new)]
+    (doseq [changed-setting (into (set (keys d1))
+                                  (set (keys d2)))]
+      (when-let [on-change (get-in rs [(keyword changed-setting) :on-change])]
+        (on-change (clojure.core/get old changed-setting) (clojure.core/get new changed-setting))))))
+
+(add-watch @#'cache/cache* :call-on-change call-on-change)
+
 ;;; +----------------------------------------------------------------------------------------------------------------+
 ;;; |                                                      get                                                       |
 ;;; +----------------------------------------------------------------------------------------------------------------+
@@ -382,6 +400,7 @@
                :description nil
                :type        setting-type
                :default     default
+               :on-change   nil
                :getter      (partial (default-getter-for-type setting-type) setting-name)
                :setter      (partial (default-setter-for-type setting-type) setting-name)
                :tag         (default-tag-for-type setting-type)
diff --git a/src/metabase/public_settings.clj b/src/metabase/public_settings.clj
index 1c852be0b37b43a39035355e463565ccb297c42e..c73cf77e1506c97c22dadbc914043a0bb3f42cb6 100644
--- a/src/metabase/public_settings.clj
+++ b/src/metabase/public_settings.clj
@@ -73,11 +73,9 @@
   (str  (deferred-tru "The default language for this Metabase instance.")
         " "
         (deferred-tru "This only applies to emails, Pulses, etc. Users'' browsers will specify the language used in the user interface."))
-  :type    :string
-  :setter  (fn [new-value]
-             (setting/set-string! :site-locale new-value)
-             (set-locale new-value))
-  :default "en")
+  :type      :string
+  :on-change (fn [_ new-value] (when new-value (set-locale new-value)))
+  :default   "en")
 
 (defsetting admin-email
   (deferred-tru "The email address users should be referred to if they encounter a problem."))
diff --git a/src/metabase/query_processor/middleware/parameters/sql.clj b/src/metabase/query_processor/middleware/parameters/sql.clj
index dd3c1922a03a287cabe8ab9e921a1f8b0a20344e..9241ec8da4f43393aa7872d367205a7329013949 100644
--- a/src/metabase/query_processor/middleware/parameters/sql.clj
+++ b/src/metabase/query_processor/middleware/parameters/sql.clj
@@ -236,6 +236,7 @@
   [base-type :- su/FieldType, value]
   (cond
     (isa? base-type :type/UUID) (UUID/fromString value)
+    (isa? base-type :type/Number) (value->number value)
     :else                       value))
 
 (s/defn ^:private parse-value-for-type :- ParamValue
diff --git a/src/metabase/sync/sync_metadata/tables.clj b/src/metabase/sync/sync_metadata/tables.clj
index 465852f44b94c1b3f88ab401b9115c2d4df51541..05f2f18b2c6b0a01cf26a5a2708463ee1a990339 100644
--- a/src/metabase/sync/sync_metadata/tables.clj
+++ b/src/metabase/sync/sync_metadata/tables.clj
@@ -71,7 +71,9 @@
     #"^databasechangelog$"
     #"^databasechangeloglock$"
     ;; Lobos
-    #"^lobos_migrations$"})
+    #"^lobos_migrations$"
+    ;; MSSQL
+    #"^syncobj_0x.*"})
 
 (s/defn ^:private is-crufty-table? :- s/Bool
   "Should we give newly created TABLE a `visibility_type` of `:cruft`?"
diff --git a/src/metabase/util/i18n.clj b/src/metabase/util/i18n.clj
index a89718d19eeb0f22e5e43aad960ff10a67ce5956..e5fd099d0e0a6418c9cbeb4ab435f651e14e103a 100644
--- a/src/metabase/util/i18n.clj
+++ b/src/metabase/util/i18n.clj
@@ -23,19 +23,25 @@
   to (such as a typo in the translated version of the string), log the failure but return the original (untranslated)
   string. This is a workaround for translations that, due to a typo, will fail to parse using Java's message
   formatter."
-  [ns-str msg args]
+  [locale ns-str msg args]
   (try
-    (apply i18n/translate ns-str (i18n/user-locale) msg args)
+    (apply i18n/translate ns-str (locale) msg args)
     (catch IllegalArgumentException e
       ;; Not translating this string to prevent an unfortunate stack overflow. If this string happened to be the one
       ;; that had the typo, we'd just recur endlessly without logging an error.
       (log/errorf e "Unable to translate string '%s'" msg)
       msg)))
 
+(def ^:private translate-system-locale
+  (partial translate i18n/system-locale))
+
+(def ^:private translate-user-locale
+  (partial translate i18n/user-locale))
+
 (p.types/defrecord+ UserLocalizedString [ns-str msg args]
   Object
   (toString [_]
-    (translate ns-str msg args))
+    (translate-user-locale ns-str msg args))
   schema.core.Schema
   (explain [this]
     (str this)))
@@ -43,7 +49,7 @@
 (p.types/defrecord+ SystemLocalizedString [ns-str msg args]
   Object
   (toString [_]
-    (translate ns-str msg args))
+    (translate-system-locale ns-str msg args))
   s/Schema
   (explain [this]
     (str this)))
diff --git a/test/metabase/models/setting/cache_test.clj b/test/metabase/models/setting/cache_test.clj
index 0aa585844e80a12fcd3bcd985d7a23fb0263cbe0..32b2f68a71be826faccd26c63f720b717cde59cc 100644
--- a/test/metabase/models/setting/cache_test.clj
+++ b/test/metabase/models/setting/cache_test.clj
@@ -2,7 +2,9 @@
   (:require [clojure.core.memoize :as memoize]
             [expectations :refer [expect]]
             [honeysql.core :as hsql]
-            [metabase.db :as mdb]
+            [metabase
+             [db :as mdb]
+             [public-settings :as public-settings]]
             [metabase.models
              [setting :refer [Setting]]
              [setting-test :as setting-test]]
@@ -151,3 +153,28 @@
       (setting-test/toucan-name "Batman Toucan"))
     (setting-test/test-setting-1 "Batman")
     (setting-test/toucan-name)))
+
+;; sets site locale setting
+(expect
+  "fr"
+  (let [original-locale (java.util.Locale/getDefault)]
+    (try (let [new-language (do (clear-cache!)
+                                (public-settings/site-locale "en")
+                                (simulate-another-instance-updating-setting! :site-locale "fr")
+                                (flush-memoized-results-for-should-restore-cache!)
+                                (public-settings/site-locale))]
+           new-language)
+         (finally (java.util.Locale/setDefault original-locale)))))
+
+;; sets java util locale
+(expect
+  "fr"
+  (let [original-locale (java.util.Locale/getDefault)]
+    (try (let [new-language (do (clear-cache!)
+                                (public-settings/site-locale "en")
+                                (simulate-another-instance-updating-setting! :site-locale "fr")
+                                (flush-memoized-results-for-should-restore-cache!)
+                                (public-settings/site-locale)
+                                (.getLanguage (java.util.Locale/getDefault)))]
+           new-language)
+         (finally (java.util.Locale/setDefault original-locale)))))
diff --git a/test/metabase/query_processor/middleware/parameters/sql_test.clj b/test/metabase/query_processor/middleware/parameters/sql_test.clj
index 1d73d7d6ee72183d5ef644f9be0abf66d8e633a0..4911bc5a69350fd91809d7b52f4eb014102f7de1 100644
--- a/test/metabase/query_processor/middleware/parameters/sql_test.clj
+++ b/test/metabase/query_processor/middleware/parameters/sql_test.clj
@@ -314,6 +314,17 @@
    :param nil}
   (into {} (#'sql/value-for-tag {:name "checkin_date", :display-name "Checkin Date", :type :dimension, :dimension [:field-id (data/id :checkins :date)]}
                                 nil)))
+;; dimension -- id requiring casting
+(expect
+  {:field {:name      "ID"
+           :parent_id nil
+           :table_id  (data/id :checkins)
+           :base_type :type/BigInteger}
+   :param {:type   :id
+           :target [:dimension [:template-tag "id"]]
+           :value  5}}
+  (into {} (#'sql/value-for-tag {:name "id", :display-name "ID", :type :dimension, :dimension [:field-id (data/id :checkins :id)]}
+                                [{:type :id, :target [:dimension [:template-tag "id"]], :value "5"}])))
 
 ;; dimension -- required but unspecified
 (expect Exception
diff --git a/test/metabase/sync/analyze/fingerprint/insights_test.clj b/test/metabase/sync/analyze/fingerprint/insights_test.clj
index 375e2847853ed14ea25b5ac16f14fe053d897b78..c2be0ca102796cd5aa8b14f09a00094999dfcf50 100644
--- a/test/metabase/sync/analyze/fingerprint/insights_test.clj
+++ b/test/metabase/sync/analyze/fingerprint/insights_test.clj
@@ -121,7 +121,7 @@
     :slope          -7.671473413418271,
     :offset         137234.92983406168,
     :best-fit       [:* 1.5672560913548484E227 [:exp [:* -0.02899533549378612 :x]]],
-    :unit           :day
+    :unit           :day,
     :col            nil}
    {:last-value     2525,
     :previous-value 3311,
@@ -129,7 +129,7 @@
     :slope          -498.764272733624,
     :offset         8915371.843617931,
     :best-fit       [:+ 8915371.843617931 [:* -498.764272733624 :x]],
-    :col            nil
+    :col            nil,
     :unit           :day}]
   (transduce identity
              (insights [{:base_type :type/DateTime} {:base_type :type/Number} {:base_type :type/Number}])
diff --git a/yarn.lock b/yarn.lock
index 4b2d1aa3bba083a40aa1332448c06cba0ac81df4..517e735142972e7ede9f88852d259f619a9c2fd2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2043,6 +2043,11 @@ big.js@^3.1.3:
   resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
   integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==
 
+bignumber.js@^7.0.0:
+  version "7.2.1"
+  resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f"
+  integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==
+
 bin-links@^1.1.0:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.2.tgz#fb74bd54bae6b7befc6c6221f25322ac830d9757"
@@ -7602,6 +7607,13 @@ jsesc@~0.5.0:
   resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
   integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
 
+json-bigint@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-0.3.0.tgz#0ccd912c4b8270d05f056fbd13814b53d3825b1e"
+  integrity sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=
+  dependencies:
+    bignumber.js "^7.0.0"
+
 json-loader@^0.5.4:
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"