diff --git a/.flowconfig b/.flowconfig index c123423757d38d0e13cd4caa3cc12824217e3150..e21ba0049ace69bc07f47807ab6318f3713722d8 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,7 +1,6 @@ [ignore] .*/node_modules/react/node_modules/.* .*/node_modules/postcss-import/node_modules/.* -.*/node_modules/@kadira/storybook/node_modules/.* .*/node_modules/.*/\(lib\|test\).*\.json$ [include] diff --git a/.reduxrc b/.reduxrc deleted file mode 100644 index e096200b91dd761ee5586669caeb146152ef07f5..0000000000000000000000000000000000000000 --- a/.reduxrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "sourceBase":"frontend/src/metabase", - "testBase":"frontend/test/unit", - "smartPath":"containers", - "dumbPath":"components", - "fileCasing":"default" -} diff --git a/.storybook/config.js b/.storybook/config.js deleted file mode 100644 index 0ef92f321c69341055af15a244c5f16f5f364871..0000000000000000000000000000000000000000 --- a/.storybook/config.js +++ /dev/null @@ -1,7 +0,0 @@ -import { configure } from '@kadira/storybook'; - -function loadStories() { - require('../frontend/stories/'); -} - -configure(loadStories, module); diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js deleted file mode 100644 index 46f15dcaebf4c603a21c3d8a7c3206919e130eeb..0000000000000000000000000000000000000000 --- a/.storybook/webpack.config.js +++ /dev/null @@ -1,34 +0,0 @@ -const path = require('path'); - -const WEBPACK_CONFIG = require("../webpack.config"); - -var SRC_PATH = path.resolve(__dirname, '../frontend/src/metabase'); - -var CSS_CONFIG = { - localIdentName: "[name]__[local]___[hash:base64:5]", - restructuring: false, - compatibility: true -} - -module.exports = { - module: { - loaders: [ - { - test: /\.json$/, - loader: "json-loader" - }, - { - test: /\.css?$/, - loaders: [ "style", "css-loader?" + JSON.stringify(CSS_CONFIG), "postcss-loader" ] - } - ] - }, - resolve: { - extensions: ["", ".webpack.js", ".web.js", ".js", ".jsx", ".css"], - alias: { - 'metabase': SRC_PATH, - 'style': SRC_PATH + '/css/core' - } - }, - postcss: WEBPACK_CONFIG.postcss -}; diff --git a/OSX/Metabase/Backend/TaskHealthChecker.m b/OSX/Metabase/Backend/TaskHealthChecker.m index 6a4b9d8a3009dcfc0aaf4b2708d99b3dc7436beb..cfb2221e83b6598f917674465d80161801dd8822 100644 --- a/OSX/Metabase/Backend/TaskHealthChecker.m +++ b/OSX/Metabase/Backend/TaskHealthChecker.m @@ -9,10 +9,10 @@ #import "TaskHealthChecker.h" /// Check out health every this many seconds -static const CGFloat HealthCheckIntervalSeconds = 1.2f; +static const CGFloat HealthCheckIntervalSeconds = 2.0f; /// This number should be lower than HealthCheckIntervalSeconds so requests don't end up piling up -static const CGFloat HealthCheckRequestTimeout = 0.25f; +static const CGFloat HealthCheckRequestTimeout = 1.75f; /// After this many seconds of being unhealthy, consider the task timed out so it can be killed static const CFTimeInterval TimeoutIntervalSeconds = 60.0f; @@ -50,7 +50,7 @@ static const CFTimeInterval TimeoutIntervalSeconds = 60.0f; [self resetTimeout]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ self.healthCheckTimer = [NSTimer timerWithTimeInterval:HealthCheckIntervalSeconds target:self selector:@selector(checkHealth) userInfo:nil repeats:YES]; self.healthCheckTimer.tolerance = HealthCheckIntervalSeconds / 2.0f; [[NSRunLoop mainRunLoop] addTimer:self.healthCheckTimer forMode:NSRunLoopCommonModes]; @@ -91,8 +91,9 @@ static const CFTimeInterval TimeoutIntervalSeconds = 60.0f; } - (void)checkHealth { + // run the health check on the high-priorty GCD queue because it's imperative that it complete so we can get an accurate picture of Mac App health __weak TaskHealthChecker *weakSelf = self; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [weakSelf checkHealth:^(BOOL healthy) { if (!healthy) NSLog(@"😷"); if (healthy && !weakSelf.healthy) NSLog(@"✅"); diff --git a/docs/administration-guide/databases/cratedb.md b/docs/administration-guide/databases/cratedb.md index dcc6f5da89561b51876db3810b8a325069ad55d1..10864759412c4e9b516080acb1db35ec1e27278a 100644 --- a/docs/administration-guide/databases/cratedb.md +++ b/docs/administration-guide/databases/cratedb.md @@ -15,4 +15,8 @@ Starting in v0.18.0 Metabase provides a driver for connecting to CrateDB directl 3. Click the `Save` button. Done. -Metabase will now begin inspecting your CrateDB Dataset and finding any tables and fields to build up a sense for the schema. Give it a little bit of time to do its work and then you're all set to start querying. \ No newline at end of file +Metabase will now begin inspecting your CrateDB Dataset and finding any tables and fields to build up a sense for the schema. Give it a little bit of time to do its work and then you're all set to start querying. + +### Known limitations + +* Columns/Fields of type `object_array` are deactivated and not exposed. However, their nested fields are listed and also supported for queries. \ No newline at end of file diff --git a/docs/api-documentation.md b/docs/api-documentation.md index 53bd42dfedfb3aecab2292023250be8315415ad3..72bf4b3df84005d9816d8b543b1d751d18f28eec 100644 --- a/docs/api-documentation.md +++ b/docs/api-documentation.md @@ -1,4 +1,4 @@ -# API Documentation for Metabase v0.23.0-snapshot +# API Documentation for Metabase v0.24.0-snapshot ## `GET /api/activity/` @@ -150,6 +150,8 @@ Run the query associated with a Card. * **`parameters`** +* **`ignore_cache`** value may be nil, or if non-nil, value must be a boolean. + ## `POST /api/card/:card-id/query/csv` @@ -193,7 +195,7 @@ Update a `Card`. * **`visualization_settings`** value may be nil, or if non-nil, value must be a map. -* **`description`** value may be nil, or if non-nil, value must be a non-blank string. +* **`description`** value may be nil, or if non-nil, value must be a string. * **`archived`** value may be nil, or if non-nil, value must be a boolean. @@ -420,7 +422,7 @@ Update a `Dashboard`. * **`points_of_interest`** value may be nil, or if non-nil, value must be a non-blank string. -* **`description`** value may be nil, or if non-nil, value must be a non-blank string. +* **`description`** value may be nil, or if non-nil, value must be a string. * **`show_in_getting_started`** value may be nil, or if non-nil, value must be a non-blank string. @@ -587,7 +589,7 @@ You must be a superuser to do this. ## `POST /api/dataset/` -Execute an MQL query and retrieve the results as JSON. +Execute a query and retrieve the results in the usual format. ##### PARAMS: @@ -1286,6 +1288,8 @@ Create a new `Pulse`. * **`channels`** value must be an array. Each value must be a map. The array cannot be empty. +* **`skip_if_empty`** value must be a boolean. + ## `POST /api/pulse/test` @@ -1299,6 +1303,8 @@ Test send an unsaved pulse. * **`channels`** value must be an array. Each value must be a map. The array cannot be empty. +* **`skip_if_empty`** value must be a boolean. + ## `PUT /api/pulse/:id` @@ -1314,6 +1320,8 @@ Update a `Pulse` with ID. * **`channels`** value must be an array. Each value must be a map. The array cannot be empty. +* **`skip_if_empty`** value must be a boolean. + ## `GET /api/revision/` @@ -1482,8 +1490,6 @@ Send a reset email when user has forgotten their password. * **`remote-address`** -* **`request`** - ## `POST /api/session/google_auth` @@ -1561,8 +1567,6 @@ Special endpoint for creating the first user during setup. * **`first_name`** value must be a non-blank string. -* **`request`** - * **`password`** Insufficient password strength * **`name`** @@ -1786,7 +1790,7 @@ Update a user's password. ## `PUT /api/user/:id/qbnewb` -Indicate that a user has been informed about the vast intricacies of 'the' QueryBuilder. +Indicate that a user has been informed about the vast intricacies of 'the' Query Builder. ##### PARAMS: diff --git a/docs/operations-guide/running-metabase-on-elastic-beanstalk.md b/docs/operations-guide/running-metabase-on-elastic-beanstalk.md index d1401a0d2cc06361a0e71c7fe67356ea89db6099..6977c4175ea57e2eaa7cbd6d9559b7e04f5bdba6 100644 --- a/docs/operations-guide/running-metabase-on-elastic-beanstalk.md +++ b/docs/operations-guide/running-metabase-on-elastic-beanstalk.md @@ -46,16 +46,19 @@ For the environment settings we want to make the following selections:  -This will run our Metabase application using [Docker](https://www.docker.com) under the hood. This will use the official Metabase Docker image which is [published on Dockerhub](https://hub.docker.com/r/metabase/metabase/) +This will run our Metabase application using [Docker](https://www.docker.com) under the hood. +This will use the official Metabase Docker image which is [published on Dockerhub](https://hub.docker.com/r/metabase/metabase/). -When your environment type settings look like the above then go ahead and click `Next` +When your environment type settings look like the above then go ahead and click `Next`. ### Application Version -The application version describes the exact binary you wish to deploy to your Elastic Beanstalk application. Metabase provides a pre-built AWS Elastic Beanstalk application version which can be linked to directly. Simply enter the following url in the `S3 URL` textbox: +The application version describes the exact binary you wish to deploy to your Elastic Beanstalk application. +Metabase provides a pre-built AWS Elastic Beanstalk application version which can be linked to directly. +Simply enter the following url in the `S3 URL` textbox: -http://downloads.metabase.com/{{ site.latest_version }}/metabase-aws-eb.zip +https://s3.amazonaws.com/downloads.metabase.com/{{ site.latest_version }}/metabase-aws-eb.zip Leave all the settings under Deployment Limits on their defaults. These settings won't impact Metabase. @@ -64,7 +67,9 @@ Leave all the settings under Deployment Limits on their defaults. These setting ### Environment Information -Here you are given a chance to pick a name and url that you want to use for running Metabase instance. Feel free to get creative, just remember that the URL for your Metabase instance must be unique across all AWS Elastic Beanstalk deployments, so you'll have to pick something nobody else is already using. +Here you are given a chance to pick a name and url that you want to use for running Metabase instance. +Feel free to get creative, just remember that the URL for your Metabase instance must be unique across all AWS Elastic Beanstalk deployments, +so you'll have to pick something nobody else is already using. We often recommend something like `mycompanyname-metabase` diff --git a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx index b3e122cbc78e59a1dedd976dc1c45c2e8ab5cbe2..942463586a2f08ce7f67c9fccadee684975191d9 100644 --- a/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx +++ b/frontend/src/metabase/admin/databases/containers/DatabaseEditApp.jsx @@ -2,6 +2,7 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; +import title from "metabase/hoc/Title"; import MetabaseSettings from "metabase/lib/settings"; import DeleteDatabaseModal from "../components/DeleteDatabaseModal.jsx"; @@ -41,6 +42,7 @@ const mapDispatchToProps = { }; @connect(mapStateToProps, mapDispatchToProps) +@title(({ database }) => database && database.name) export default class DatabaseEditApp extends Component { static propTypes = { database: PropTypes.object, diff --git a/frontend/src/metabase/admin/permissions/routes.jsx b/frontend/src/metabase/admin/permissions/routes.jsx index 47308bb5699934df97207a1de4e079202407ddd8..23c3df9119eedcda2a0710f7a4c4a5b29718097b 100644 --- a/frontend/src/metabase/admin/permissions/routes.jsx +++ b/frontend/src/metabase/admin/permissions/routes.jsx @@ -1,5 +1,7 @@ + import React from "react"; -import { Route, IndexRedirect } from 'react-router'; +import { Route } from "metabase/hoc/Title"; +import { IndexRedirect } from 'react-router'; import DataPermissionsApp from "./containers/DataPermissionsApp.jsx"; import DatabasesPermissionsApp from "./containers/DatabasesPermissionsApp.jsx"; @@ -7,7 +9,7 @@ import SchemasPermissionsApp from "./containers/SchemasPermissionsApp.jsx"; import TablesPermissionsApp from "./containers/TablesPermissionsApp.jsx"; const getRoutes = (store) => - <Route path="permissions" component={DataPermissionsApp}> + <Route title="Permissions" path="permissions" component={DataPermissionsApp}> <IndexRedirect to="databases" /> <Route path="databases" component={DatabasesPermissionsApp} /> <Route path="databases/:databaseId/schemas" component={SchemasPermissionsApp} /> diff --git a/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx b/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx index 0928a1420d60e83ec6c58c92eec2ed837016f83b..83e121977c4634a7a59b361963bfa73e21636f57 100644 --- a/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx +++ b/frontend/src/metabase/admin/settings/containers/SettingsEditorApp.jsx @@ -2,6 +2,8 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; import { Link } from "react-router"; import { connect } from "react-redux"; + +import title from "metabase/hoc/Title"; import MetabaseAnalytics from "metabase/lib/analytics"; import AdminLayout from "metabase/components/AdminLayout.jsx"; @@ -41,6 +43,7 @@ const mapDispatchToProps = { } @connect(mapStateToProps, mapDispatchToProps) +@title(({ activeSection }) => activeSection && activeSection.name) export default class SettingsEditorApp extends Component { static propTypes = { sections: PropTypes.array.isRequired, diff --git a/frontend/src/metabase/app.js b/frontend/src/metabase/app.js index 985f7f93403dae71c154979f5d5b5af8f63696ab..770bf2d09f108593e281d5e8641a5385e5c7c5bd 100644 --- a/frontend/src/metabase/app.js +++ b/frontend/src/metabase/app.js @@ -16,6 +16,7 @@ import { getStore } from './store' import { refreshSiteSettings } from "metabase/redux/settings"; import { setErrorPage } from "metabase/redux/app"; +import { clearCurrentUser } from "metabase/redux/user"; import { Router, useRouterHistory } from "react-router"; import { createHistory } from 'history' @@ -74,6 +75,7 @@ function _init(reducers, getRoutes, callback) { if (url === "/api/user/current") { return } + store.dispatch(clearCurrentUser()); store.dispatch(push("/auth/login")); }); diff --git a/frontend/src/metabase/auth/auth.js b/frontend/src/metabase/auth/auth.js index fbd5aaec514b3b9fdd187a1c8c473177edc60a87..b75b5db49a18de80cc2b5e3cf80e31f5d4ec263d 100644 --- a/frontend/src/metabase/auth/auth.js +++ b/frontend/src/metabase/auth/auth.js @@ -15,7 +15,8 @@ import { SessionApi } from "metabase/services"; // login -export const login = createThunkAction("AUTH_LOGIN", function(credentials, redirectUrl) { +export const LOGIN = "metabase/auth/LOGIN"; +export const login = createThunkAction(LOGIN, function(credentials, redirectUrl) { return async function(dispatch, getState) { if (!MetabaseUtils.validEmail(credentials.email)) { @@ -41,7 +42,8 @@ export const login = createThunkAction("AUTH_LOGIN", function(credentials, redir // login Google -export const loginGoogle = createThunkAction("AUTH_LOGIN_GOOGLE", function(googleUser, redirectUrl) { +export const LOGIN_GOOGLE = "metabase/auth/LOGIN_GOOGLE"; +export const loginGoogle = createThunkAction(LOGIN_GOOGLE, function(googleUser, redirectUrl) { return async function(dispatch, getState) { try { let newSession = await SessionApi.createWithGoogleAuth({ @@ -70,7 +72,8 @@ export const loginGoogle = createThunkAction("AUTH_LOGIN_GOOGLE", function(googl }); // logout -export const logout = createThunkAction("AUTH_LOGOUT", function() { +export const LOGOUT = "metabase/auth/LOGOUT"; +export const logout = createThunkAction(LOGOUT, function() { return function(dispatch, getState) { // TODO: as part of a logout we want to clear out any saved state that we have about anything @@ -86,7 +89,8 @@ export const logout = createThunkAction("AUTH_LOGOUT", function() { }); // passwordReset -export const passwordReset = createThunkAction("AUTH_PASSWORD_RESET", function(token, credentials) { +export const PASSWORD_RESET = "metabase/auth/PASSWORD_RESET" +export const passwordReset = createThunkAction(PASSWORD_RESET, function(token, credentials) { return async function(dispatch, getState) { if (credentials.password !== credentials.password2) { @@ -123,16 +127,17 @@ export const passwordReset = createThunkAction("AUTH_PASSWORD_RESET", function(t // reducers const loginError = handleActions({ - ["AUTH_LOGIN"]: { next: (state, { payload }) => payload ? payload : null }, - ["AUTH_LOGIN_GOOGLE"]: { next: (state, { payload }) => payload ? payload : null } + [LOGIN]: { next: (state, { payload }) => payload ? payload : null }, + [LOGIN_GOOGLE]: { next: (state, { payload }) => payload ? payload : null } }, null); + const resetSuccess = handleActions({ - ["AUTH_PASSWORD_RESET"]: { next: (state, { payload }) => payload.success } + [PASSWORD_RESET]: { next: (state, { payload }) => payload.success } }, false); const resetError = handleActions({ - ["AUTH_PASSWORD_RESET"]: { next: (state, { payload }) => payload.error } + [PASSWORD_RESET]: { next: (state, { payload }) => payload.error } }, null); export default combineReducers({ diff --git a/frontend/src/metabase/components/Button.info.js b/frontend/src/metabase/components/Button.info.js new file mode 100644 index 0000000000000000000000000000000000000000..376f3fb913b1e51bf1fee59c8b8a907c40cc5a6a --- /dev/null +++ b/frontend/src/metabase/components/Button.info.js @@ -0,0 +1,14 @@ +import React from "react"; +import Button from "metabase/components/Button"; + +export const component = Button; + +export const description = ` +Metabase's main button component. +`; + +export const examples = { + "": <Button>Clickity click</Button>, + "primary": <Button primary>Clickity click</Button>, + "with an icon": <Button icon='star'>Clickity click</Button> +}; diff --git a/frontend/src/metabase/components/CheckBox.info.js b/frontend/src/metabase/components/CheckBox.info.js new file mode 100644 index 0000000000000000000000000000000000000000..be9711d551258d1266898a28feaf373b1c35899f --- /dev/null +++ b/frontend/src/metabase/components/CheckBox.info.js @@ -0,0 +1,14 @@ +import React from "react"; +import CheckBox from "metabase/components/CheckBox"; + +export const component = CheckBox; + +export const description = ` +A standard checkbox. +`; + +export const examples = { + "off": <CheckBox />, + "on": <CheckBox checked />, + "on inverted": <CheckBox style={{ color: "#509EE3" }} invertChecked checked /> +}; diff --git a/frontend/src/metabase/components/HeaderBar.jsx b/frontend/src/metabase/components/HeaderBar.jsx index c82d1a23020f8c26cf0150d3c62ad054842d7171..b12316ae08722d8e590d6e572cc85d62e14b0683 100644 --- a/frontend/src/metabase/components/HeaderBar.jsx +++ b/frontend/src/metabase/components/HeaderBar.jsx @@ -42,15 +42,15 @@ export default class Header extends Component { } return ( - <div className={cx("QueryBuilder-section flex align-center", className)}> - <div className={cx("py1 relative flex-full", { "pt2": badge })}> + <div className={cx("QueryBuilder-section pt2 sm-pt0 flex align-center", className)}> + <div className={cx("px2 sm-px0 pt2 relative flex-full")}> { badge && - <div className="absolute top left">{badge}</div> + <div className="absolute top left ml2 sm-ml0">{badge}</div> } {titleAndDescription} </div> - <div className="flex-align-right"> + <div className="flex-align-right hide sm-show"> {buttons} </div> </div> diff --git a/frontend/src/metabase/components/StackedCheckBox.info.js b/frontend/src/metabase/components/StackedCheckBox.info.js new file mode 100644 index 0000000000000000000000000000000000000000..69a97375d36ae330d907dc25c0ed6f90a39fa0ca --- /dev/null +++ b/frontend/src/metabase/components/StackedCheckBox.info.js @@ -0,0 +1,14 @@ +import React from "react"; +import StackedCheckBox from "metabase/components/StackedCheckBox"; + +export const component = StackedCheckBox; + +export const description = ` +A stacked checkbox, representing "all" items. +`; + +export const examples = { + "off": <StackedCheckBox />, + "on": <StackedCheckBox checked />, + "on inverted": <StackedCheckBox style={{ color: "#509EE3" }} invertChecked checked /> +}; diff --git a/frontend/src/metabase/components/Toggle.info.js b/frontend/src/metabase/components/Toggle.info.js new file mode 100644 index 0000000000000000000000000000000000000000..55ac49dd26cd1cb66fcbd6010fb285531639db25 --- /dev/null +++ b/frontend/src/metabase/components/Toggle.info.js @@ -0,0 +1,13 @@ +import React from "react"; +import Toggle from "metabase/components/Toggle"; + +export const component = Toggle; + +export const description = ` +A standard toggle. +`; + +export const examples = { + "off": <Toggle value={false} />, + "on": <Toggle value={true} /> +}; diff --git a/frontend/src/metabase/dashboard/components/parameters/widgets/CategoryWidget.jsx b/frontend/src/metabase/dashboard/components/parameters/widgets/CategoryWidget.jsx index 1d19376aee2b7e29ddeea6c7263bb000ceb2ade5..c995b515c3a80d93ac30d063c311d73cd4f50c16 100644 --- a/frontend/src/metabase/dashboard/components/parameters/widgets/CategoryWidget.jsx +++ b/frontend/src/metabase/dashboard/components/parameters/widgets/CategoryWidget.jsx @@ -74,7 +74,7 @@ export default class CategoryWidget extends Component<*, Props, State> { return ( <div style={{ maxWidth: 200 }}> - { values.length > 10 && regex && + { values.length > 10 && <div className="p1"> <ListSearchField onChange={this.updateSearchText} diff --git a/frontend/src/metabase/dashboard/containers/DashboardApp.jsx b/frontend/src/metabase/dashboard/containers/DashboardApp.jsx index 8e704cde2cdc3225d7c6a29d626cc344f587e87d..568e01fefc0fa1fc671e1ce89d0ce0a76104fa86 100644 --- a/frontend/src/metabase/dashboard/containers/DashboardApp.jsx +++ b/frontend/src/metabase/dashboard/containers/DashboardApp.jsx @@ -3,6 +3,7 @@ import React, { Component } from "react"; import { connect } from "react-redux"; import { push } from "react-router-redux"; +import title from "metabase/hoc/Title"; import Dashboard from "../components/Dashboard.jsx"; @@ -40,6 +41,7 @@ const mapDispatchToProps = { } @connect(mapStateToProps, mapDispatchToProps) +@title(({ dashboard }) => dashboard && dashboard.name) export default class DashboardApp extends Component { render() { return <Dashboard {...this.props} />; diff --git a/frontend/src/metabase/dashboard/containers/ParameterWidget.jsx b/frontend/src/metabase/dashboard/containers/ParameterWidget.jsx index cb81c3845169edfde21e6791528d0063d352d951..9f7ab1ba4a955fc5f7edd74b0fcb3219083b4338 100644 --- a/frontend/src/metabase/dashboard/containers/ParameterWidget.jsx +++ b/frontend/src/metabase/dashboard/containers/ParameterWidget.jsx @@ -36,11 +36,13 @@ export default class ParameterWidget extends Component { } static propTypes = { - parameter: PropTypes.object + parameter: PropTypes.object, + commitImmediately: PropTypes.object }; static defaultProps = { parameter: null, + commitImmediately: false } getValues() { @@ -56,7 +58,7 @@ export default class ParameterWidget extends Component { } renderPopover(value, setValue, placeholder, isFullscreen) { - const {parameter, editingParameter} = this.props; + const {parameter, editingParameter, commitImmediately} = this.props; const isEditingParameter = !!(editingParameter && editingParameter.id === parameter.id); const values = this.getValues(); return ( @@ -70,6 +72,7 @@ export default class ParameterWidget extends Component { placeholder={placeholder} focusChanged={this.focusChanged} isFullscreen={isFullscreen} + commitImmediately={commitImmediately} /> ); } diff --git a/frontend/src/metabase/dashboard/containers/Parameters.jsx b/frontend/src/metabase/dashboard/containers/Parameters.jsx index 27922677a5f5ab5172ed0918ac7f465698bb0861..80a6b3963078581605584f5b654bb11ab84a74de 100644 --- a/frontend/src/metabase/dashboard/containers/Parameters.jsx +++ b/frontend/src/metabase/dashboard/containers/Parameters.jsx @@ -11,6 +11,7 @@ export default class Parameters extends Component { defaultProps = { syncQueryString: false, vertical: false, + commitImmediately: false } componentWillMount() { @@ -62,7 +63,8 @@ export default class Parameters extends Component { editingParameter, setEditingParameter, isEditing, isFullscreen, isNightMode, isQB, setParameterName, setParameterValue, setParameterDefaultValue, removeParameter, - vertical + vertical, + commitImmediately } = this.props; const parameters = this._parametersWithValues(); @@ -88,6 +90,8 @@ export default class Parameters extends Component { setValue={(value) => setParameterValue(parameter.id, value)} setDefaultValue={(value) => setParameterDefaultValue(parameter.id, value)} remove={() => removeParameter(parameter.id)} + + commitImmediately={commitImmediately} /> ) } </div> diff --git a/frontend/src/metabase/hoc/Routeless.jsx b/frontend/src/metabase/hoc/Routeless.jsx index f231e6c2798bfb476cc904b66b09f6c7b2e1b072..1cea1278cec640220a68af2f42bd7aaff03d90b6 100644 --- a/frontend/src/metabase/hoc/Routeless.jsx +++ b/frontend/src/metabase/hoc/Routeless.jsx @@ -24,6 +24,7 @@ export default (ComposedComponent) => class extends Component { static displayName = "Routeless["+(ComposedComponent.displayName || ComposedComponent.name)+"]"; _state: any; + _timeout: any; componentWillMount() { const push = this.props._routeless_push; @@ -41,13 +42,23 @@ export default (ComposedComponent) => class extends Component { // if the state previously was the saved one and is now not, then we probably // hit the back button, so close the wrapped component if (location.state === this._state && nextLocation.state !== this._state) { - this.props.onClose(); + // perform this in a timeout because the component may be unmounted anyway, in which + // case calling onClose again may cause problems. + // alternatively may be able to tighten up the logic above + this._timeout = setTimeout(() => { + this.props.onClose(); + }, 100); } } componentWillUnmount() { const location = this.props._routeless_location; const goBack = this.props._routeless_goBack; + + if (this._timeout != null) { + clearTimeout(this._timeout); + } + // if we unmount (e.x. hit the close button which calls onClose directly) and still have the // same state then go back to the original state // NOTE: ideally we would remove the current state from the history so the forward diff --git a/frontend/src/metabase/hoc/Title.jsx b/frontend/src/metabase/hoc/Title.jsx new file mode 100644 index 0000000000000000000000000000000000000000..d150131d270ef4d6c2fca11c2f1721000be623ea --- /dev/null +++ b/frontend/src/metabase/hoc/Title.jsx @@ -0,0 +1,88 @@ +import React from "react"; + +import _ from "underscore"; + +const componentStack = []; + +let SEPARATOR = " · "; +let HIERARCHICAL = true; +let BASE_NAME = null; + +export const setSeparator = (separator) => SEPARATOR = separator; +export const setHierarchical = (hierarchical) => HIERARCHICAL = hierarchical; +export const setBaseName = (baseName) => BASE_NAME = baseName; + +const updateDocumentTitle = _.debounce(() => { + if (HIERARCHICAL) { + document.title = componentStack + .map(component => component._documentTitle) + .filter(title => title) + .reverse() + .join(SEPARATOR); + } else { + // update with the top-most title + for (let i = componentStack.length - 1; i >= 0; i--) { + let title = componentStack[i]._documentTitle; + if (title) { + if (BASE_NAME) { + title += SEPARATOR + BASE_NAME; + } + if (document.title !== title) { + document.title = title; + } + break; + } + } + } +}) + +const title = (documentTitleOrGetter) => (ComposedComponent) => + class extends React.Component { + static displayName = "Title["+(ComposedComponent.displayName || ComposedComponent.name)+"]"; + + componentWillMount() { + componentStack.push(this); + this._updateDocumentTitle(); + } + componentDidUpdate() { + this._updateDocumentTitle(); + } + componentWillUnmount() { + for (let i = 0; i < componentStack.length; i++) { + if (componentStack[i] === this) { + componentStack.splice(i, 1); + break; + } + } + this._updateDocumentTitle(); + } + + _updateDocumentTitle() { + if (typeof documentTitleOrGetter === "string") { + this._documentTitle = documentTitleOrGetter; + } else if (typeof documentTitleOrGetter === "function") { + this._documentTitle = documentTitleOrGetter(this.props); + } + updateDocumentTitle(); + } + + render() { + return <ComposedComponent {...this.props} />; + } + } + +export default title; + +import { Route as _Route } from "react-router"; + +// react-router Route wrapper that adds a `title` property +export class Route extends _Route { + static createRouteFromReactElement(element) { + if (element.props.title) { + element = React.cloneElement(element, { + component: title(element.props.title)(element.props.component || (({ children }) => children)) + }); + } + return _Route.createRouteFromReactElement(element); + } +} diff --git a/frontend/src/metabase/home/containers/HomepageApp.jsx b/frontend/src/metabase/home/containers/HomepageApp.jsx index cd5be9797e6a557cfd5b8b7b29a07a2df8e6a9fa..396d3df39ca570758f3c160f1df8014cb561ac48 100644 --- a/frontend/src/metabase/home/containers/HomepageApp.jsx +++ b/frontend/src/metabase/home/containers/HomepageApp.jsx @@ -94,7 +94,7 @@ export default class HomepageApp extends Component { <Activity {...this.props} /> </div> </div> - <div className="Layout-sidebar flex-no-shrink"> + <div className="Layout-sidebar flex-no-shrink hide sm-show"> <NextStep /> <RecentViews {...this.props} /> </div> diff --git a/frontend/src/metabase/icon_paths.js b/frontend/src/metabase/icon_paths.js index 4f6865f904cc8441540988d4bbf1be05e39ace04..c37829a1bf34736f4894d71675186dfd5477b151 100644 --- a/frontend/src/metabase/icon_paths.js +++ b/frontend/src/metabase/icon_paths.js @@ -213,6 +213,9 @@ ICON_PATHS["horizontal_bar"] = { } }; +// $FlowFixMe +ICON_PATHS["scalar"] = ICON_PATHS["number"]; + export function loadIcon(name) { var def = ICON_PATHS[name]; if (!def) { diff --git a/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap b/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..256ce8fadff3af0c4ac844740ff4c49d2ba29921 --- /dev/null +++ b/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap @@ -0,0 +1,400 @@ +exports[`Button should render "" correctly 1`] = ` +<button + className="Button "> + <div + className="flex layout-centered"> + <div> + Clickity click + </div> + </div> +</button> +`; + +exports[`Button should render "primary" correctly 1`] = ` +<button + className="Button Button--primary"> + <div + className="flex layout-centered"> + <div> + Clickity click + </div> + </div> +</button> +`; + +exports[`Button should render "with an icon" correctly 1`] = ` +<button + className="Button "> + <div + className="flex layout-centered"> + <svg + className="mr1" + fill="currentcolor" + height={14} + name="star" + size={14} + viewBox="0 0 32 32" + width={14}> + <path + d="M16 0 L21 11 L32 12 L23 19 L26 31 L16 25 L6 31 L9 19 L0 12 L11 11" /> + </svg> + <div> + Clickity click + </div> + </div> +</button> +`; + +exports[`CheckBox should render "off" correctly 1`] = ` +<div + className="cursor-pointer" + onClick={[Function]} + style={undefined}> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "white", + "border": "2px solid #ddd", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + } /> +</div> +`; + +exports[`CheckBox should render "on inverted" correctly 1`] = ` +<div + className="cursor-pointer" + onClick={[Function]} + style={ + Object { + "color": "#509EE3", + } + }> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "currentColor", + "border": "2px solid currentColor", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + }> + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "white", + } + } + viewBox="0 0 32 32" + width={12}> + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " /> + </svg> + </div> +</div> +`; + +exports[`CheckBox should render "on" correctly 1`] = ` +<div + className="cursor-pointer" + onClick={[Function]} + style={undefined}> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "white", + "border": "2px solid #ddd", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + }> + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "currentColor", + } + } + viewBox="0 0 32 32" + width={12}> + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " /> + </svg> + </div> +</div> +`; + +exports[`StackedCheckBox should render "off" correctly 1`] = ` +<span + className={undefined} + style={ + Object { + "position": "relative", + } + }> + <div + className="cursor-pointer" + onClick={[Function]} + style={ + Object { + "left": 3, + "position": "absolute", + "top": -3, + "zIndex": -1, + } + }> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "white", + "border": "2px solid #ddd", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + } /> + </div> + <div + className="cursor-pointer" + onClick={[Function]} + style={Object {}}> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "white", + "border": "2px solid #ddd", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + } /> + </div> +</span> +`; + +exports[`StackedCheckBox should render "on inverted" correctly 1`] = ` +<span + className={undefined} + style={ + Object { + "color": "#509EE3", + "position": "relative", + } + }> + <div + className="cursor-pointer" + onClick={[Function]} + style={ + Object { + "left": 3, + "position": "absolute", + "top": -3, + "zIndex": -1, + } + }> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "currentColor", + "border": "2px solid currentColor", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + }> + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "white", + } + } + viewBox="0 0 32 32" + width={12}> + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " /> + </svg> + </div> + </div> + <div + className="cursor-pointer" + onClick={[Function]} + style={Object {}}> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "currentColor", + "border": "2px solid currentColor", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + }> + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "white", + } + } + viewBox="0 0 32 32" + width={12}> + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " /> + </svg> + </div> + </div> +</span> +`; + +exports[`StackedCheckBox should render "on" correctly 1`] = ` +<span + className={undefined} + style={ + Object { + "position": "relative", + } + }> + <div + className="cursor-pointer" + onClick={[Function]} + style={ + Object { + "left": 3, + "position": "absolute", + "top": -3, + "zIndex": -1, + } + }> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "white", + "border": "2px solid #ddd", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + }> + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "currentColor", + } + } + viewBox="0 0 32 32" + width={12}> + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " /> + </svg> + </div> + </div> + <div + className="cursor-pointer" + onClick={[Function]} + style={Object {}}> + <div + style={ + Object { + "alignItems": "center", + "backgroundColor": "white", + "border": "2px solid #ddd", + "borderRadius": 4, + "display": "flex", + "height": 16, + "justifyContent": "center", + "width": 16, + } + }> + <svg + className="Icon Icon-check" + fill="currentcolor" + height={12} + name="check" + size={12} + style={ + Object { + "color": "currentColor", + } + } + viewBox="0 0 32 32" + width={12}> + <path + d="M1 14 L5 10 L13 18 L27 4 L31 8 L13 26 z " /> + </svg> + </div> + </div> +</span> +`; + +exports[`Toggle should render "off" correctly 1`] = ` +<a + className="no-decoration " + onClick={null} + style={ + Object { + "color": null, + } + } /> +`; + +exports[`Toggle should render "on" correctly 1`] = ` +<a + className="no-decoration undefined " + onClick={null} + style={ + Object { + "color": null, + } + } /> +`; diff --git a/frontend/src/metabase/internal/components.spec.js b/frontend/src/metabase/internal/components.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..b16af571e443181e0dbdd50a969ac8bd12e0f9e9 --- /dev/null +++ b/frontend/src/metabase/internal/components.spec.js @@ -0,0 +1,12 @@ +import renderer from "react-test-renderer"; + +import components from "./lib/components-node"; + +// generates a snapshot test for every example in every component's `.info.js` +components.map(({ component, examples }) => + describe(component.displayName, () => { + Object.entries(examples).map(([exampleName, element]) => + it(`should render "${exampleName}" correctly`, () => { + expect(renderer.create(element).toJSON()).toMatchSnapshot(); + })); + })); diff --git a/frontend/src/metabase/internal/components/ColorsApp.jsx b/frontend/src/metabase/internal/components/ColorsApp.jsx new file mode 100644 index 0000000000000000000000000000000000000000..7f7daa5a9c52a9b3f5c62883d424267a101268b5 --- /dev/null +++ b/frontend/src/metabase/internal/components/ColorsApp.jsx @@ -0,0 +1,20 @@ +import React from "react"; + +import cx from "classnames"; + +// eslint-disable-next-line import/no-commonjs +let colorStyles = require("!style!css?modules!postcss!metabase/css/core/colors.css"); + +const ColorsApp = () => + <div className="p2"> + {Object.entries(colorStyles).map(([name, className]) => + <div + className={cx(className, "rounded px1")} + style={{ paddingTop: "0.25em", paddingBottom: "0.25em", marginBottom: "0.25em" }} + > + {name} + </div> + )} + </div> + +export default ColorsApp; diff --git a/frontend/src/metabase/internal/components/ComponentsApp.jsx b/frontend/src/metabase/internal/components/ComponentsApp.jsx new file mode 100644 index 0000000000000000000000000000000000000000..8e50b78f36157a7b8b08220dac53883a54b873e4 --- /dev/null +++ b/frontend/src/metabase/internal/components/ComponentsApp.jsx @@ -0,0 +1,59 @@ +import React, { Component } from "react"; + +import reactElementToJSXString from "react-element-to-jsx-string"; +import components from "../lib/components-webpack"; + +const Section = ({ title, children }) => + <div className="mb2"> + <h3 className="my2">{title}</h3> + {children} + </div> + +export default class ComponentsApp extends Component { + render() { + return ( + <div className="wrapper p4"> + {components.map(({ component, description, examples }) => ( + <div> + <h2>{component.name}</h2> + { description && + <p className="my2">{description}</p> + } + { component.propTypes && + <Section title="Props"> + {Object.keys(component.propTypes).map(prop => + <div>{prop}</div> + )} + </Section> + } + { examples && + <Section title="Examples"> + {Object.entries(examples).map(([name, element]) => ( + <div className="my2"> + <h4 className="my1">{name}</h4> + <div className="flex flex-column"> + <div + className="p2 bordered flex align-center flex-full" + > + <div> + {element} + </div> + </div> + <div + className="border-left border-right border-bottom text-code" + > + <div className="p1"> + {reactElementToJSXString(element)} + </div> + </div> + </div> + </div> + ))} + </Section> + } + </div> + ))} + </div> + ); + } +} diff --git a/frontend/src/metabase/routes-internal.js b/frontend/src/metabase/internal/components/IconsApp.jsx similarity index 62% rename from frontend/src/metabase/routes-internal.js rename to frontend/src/metabase/internal/components/IconsApp.jsx index ee62feefe2ec63b6592ce38fc4df3096ca5790e0..b362ba28450f619d1f9df1ef50c29ea0d193be2a 100644 --- a/frontend/src/metabase/routes-internal.js +++ b/frontend/src/metabase/internal/components/IconsApp.jsx @@ -1,19 +1,10 @@ import React, { Component } from "react"; -import { Route, Link } from "react-router"; import Icon from "metabase/components/Icon.jsx"; -import cx from "classnames"; - const SIZES = [12, 16]; -const ListApp = () => - <ul> - <li><Link to="_internal/icons">Icons</Link></li> - <li><Link to="_internal/colors">Colors</Link></li> - </ul> - -class IconsApp extends Component { +export default class IconsApp extends Component { constructor(props) { super(props); this.state = { @@ -57,26 +48,3 @@ class IconsApp extends Component { ) } } - -// eslint-disable-next-line import/no-commonjs -let colorStyles = require("!style!css?modules!postcss!metabase/css/core/colors.css"); - -const ColorsApp = () => - <div className="p2"> - {Object.entries(colorStyles).map(([name, className]) => - <div - className={cx(className, "rounded px1")} - style={{ paddingTop: "0.25em", paddingBottom: "0.25em", marginBottom: "0.25em" }} - > - {name} - </div> - )} - </div> - -export default ( - <Route> - <Route path="list" component={ListApp} /> - <Route path="icons" component={IconsApp} /> - <Route path="colors" component={ColorsApp} /> - </Route> -); diff --git a/frontend/src/metabase/internal/lib/components-node.js b/frontend/src/metabase/internal/lib/components-node.js new file mode 100644 index 0000000000000000000000000000000000000000..b4b243aff6c979627838aa6c08e1feaa92913499 --- /dev/null +++ b/frontend/src/metabase/internal/lib/components-node.js @@ -0,0 +1,11 @@ +/*eslint-env node */ + +import path from "path"; +import fs from "fs"; + +var normalizedPath = path.join(__dirname, "..", "..", "components"); + +export default fs + .readdirSync(normalizedPath) + .filter(file => /\.info\.js$/.test(file)) + .map(file => require(path.join(normalizedPath, file))); diff --git a/frontend/src/metabase/internal/lib/components-webpack.js b/frontend/src/metabase/internal/lib/components-webpack.js new file mode 100644 index 0000000000000000000000000000000000000000..0538bfb260e332c22eb88e46fc1762be21f9f813 --- /dev/null +++ b/frontend/src/metabase/internal/lib/components-webpack.js @@ -0,0 +1,8 @@ +// import all modules in this directory (http://stackoverflow.com/a/31770875) +const req = require.context( + "metabase/components", + true, + /^(.*\.info\.(js$))[^.]*$/igm +); + +export default req.keys().map(key => req(key)); diff --git a/frontend/src/metabase/internal/routes.js b/frontend/src/metabase/internal/routes.js new file mode 100644 index 0000000000000000000000000000000000000000..ff49d8e4c6f5de1775ffc5ffcfa1976cb707674a --- /dev/null +++ b/frontend/src/metabase/internal/routes.js @@ -0,0 +1,30 @@ +import React from "react"; +import { Route, IndexRoute } from "react-router"; + +import IconsApp from "metabase/internal/components/IconsApp"; +import ColorsApp from "metabase/internal/components/ColorsApp"; +import ComponentsApp from "metabase/internal/components/ComponentsApp"; + +const PAGES = { + "Icons": IconsApp, + "Colors": ColorsApp, + "Components": ComponentsApp, +} + +const ListApp = () => + <ul> + { Object.keys(PAGES).map((name) => + <li><a href={"/_internal/"+name.toLowerCase()}>{name}</a></li> + )} + </ul> + + + +export default ( + <Route> + <IndexRoute component={ListApp} /> + { Object.entries(PAGES).map(([name, Component]) => + <Route path={name.toLowerCase()} component={Component} /> + )} + </Route> +); diff --git a/frontend/src/metabase/nav/containers/Navbar.jsx b/frontend/src/metabase/nav/containers/Navbar.jsx index 3c286bcbfaa7606cafcb486063df0cab68c61d68..a1740cf79f3fe965de2e8057f4d73a6fa3334268 100644 --- a/frontend/src/metabase/nav/containers/Navbar.jsx +++ b/frontend/src/metabase/nav/containers/Navbar.jsx @@ -110,13 +110,13 @@ export default class Navbar extends Component { renderMainNav() { return ( <nav className={cx("Nav CheckBg CheckBg-offset relative bg-brand sm-py2 sm-py1 xl-py3", this.props.className)}> - <ul className="pl4 pr1 flex align-center"> + <ul className="ml2 sm-pl4 pr1 flex align-center"> <li> <Link to="/" data-metabase-event={"Navbar;Logo"} className="NavItem cursor-pointer text-white flex align-center my1 transition-background p1"> <LogoIcon dark={true}></LogoIcon> </Link> </li> - <li className="pl3"> + <li className="pl3 hide sm-show"> <DashboardsDropdown {...this.props}> <a data-metabase-event={"Navbar;Dashboard Dropdown;Toggle"} @@ -132,17 +132,20 @@ export default class Navbar extends Component { </a> </DashboardsDropdown> </li> - <li className="pl1"> + <li className="pl1 hide sm-show"> <Link to="/questions" data-metabase-event={"Navbar;Questions"} style={this.styles.navButton} className={cx("NavItem cursor-pointer text-white text-bold no-decoration flex align-center px2 transition-background")} activeClassName="NavItem--selected">Questions</Link> </li> - <li className="pl1"> + <li className="pl1 hide sm-show"> <Link to="/pulse" data-metabase-event={"Navbar;Pulses"} style={this.styles.navButton} className={cx("NavItem cursor-pointer text-white text-bold no-decoration flex align-center px2 transition-background")} activeClassName="NavItem--selected">Pulses</Link> </li> - <li className="pl1"> + <li className="pl1 hide sm-show"> <Link to="/reference/guide" data-metabase-event={"Navbar;DataReference"} style={this.styles.navButton} className={cx("NavItem cursor-pointer text-white text-bold no-decoration flex align-center px2 transition-background")} activeClassName="NavItem--selected">Data Reference</Link> </li> - <li className="pl3"> - <Link to={Urls.question()} data-metabase-event={"Navbar;New Question"} style={this.styles.newQuestion} className="NavNewQuestion rounded inline-block bg-white text-brand text-bold cursor-pointer px2 no-decoration transition-all">New <span className="hide sm-show">Question</span></Link> + <li className="pl3 hide sm-show"> + <Link to={Urls.question()} data-metabase-event={"Navbar;New Question"} style={this.styles.newQuestion} className="NavNewQuestion rounded inline-block bg-white text-brand text-bold cursor-pointer px2 no-decoration transition-all"> + New + <span>Question</span> + </Link> </li> <li className="flex-align-right transition-background"> <div className="inline-block text-white"><ProfileLink {...this.props}></ProfileLink></div> diff --git a/frontend/src/metabase/pulse/containers/PulseEditApp.jsx b/frontend/src/metabase/pulse/containers/PulseEditApp.jsx index 60c68b4aa41af0ee53acb4adb1de150d9ef6a8b8..cc54cf9df4699f98a7e7586a0b3c3623b63fc692 100644 --- a/frontend/src/metabase/pulse/containers/PulseEditApp.jsx +++ b/frontend/src/metabase/pulse/containers/PulseEditApp.jsx @@ -3,6 +3,8 @@ import React, { Component } from "react"; import { connect } from "react-redux"; import { push } from "react-router-redux"; +import title from "metabase/hoc/Title"; + import PulseEdit from "../components/PulseEdit.jsx"; import { editPulseSelectors } from "../selectors"; @@ -39,6 +41,7 @@ const mapDispatchToProps = { }; @connect(mapStateToProps, mapDispatchToProps) +@title(({ pulse }) => pulse && pulse.name) export default class PulseEditApp extends Component { render() { return ( diff --git a/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx b/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx index 285e528400e100284e6c370c8d317912019f1290..bacd9397af7e9c28ef6b18e944c21831d1a453d1 100644 --- a/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx +++ b/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx @@ -154,7 +154,9 @@ export default class TimeseriesFilterWidget extends Component<*, Props, State> { this._popover.close(); } }} - >Apply</Button> + > + Apply + </Button> </div> </PopoverWithTrigger> ); diff --git a/frontend/src/metabase/query_builder/actions.js b/frontend/src/metabase/query_builder/actions.js index 4baf7bc67caf8d82235f288e7c414acf955ba8cb..990554e953c6c3e38a93fbc815f2b5a452947549 100644 --- a/frontend/src/metabase/query_builder/actions.js +++ b/frontend/src/metabase/query_builder/actions.js @@ -444,7 +444,7 @@ export const notifyCardCreatedFn = createThunkAction(NOTIFY_CARD_CREATED, (card) }); export const NOTIFY_CARD_UPDATED = "metabase/qb/NOTIFY_CARD_UPDATED"; -export const notifyCardUpdatedFn = createThunkAction("NOTIFY_CARD_UPDATED", (card) => { +export const notifyCardUpdatedFn = createThunkAction(NOTIFY_CARD_UPDATED, (card) => { return (dispatch, getState) => { dispatch(updateUrl(card, { dirty: false })); diff --git a/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx b/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx index 645519774829e6067f5ae4a151203d72d76bf3da..ecfa64d17dd72b8c416c139e6e67dc9b05799b9f 100644 --- a/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx +++ b/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx @@ -348,6 +348,7 @@ export default class NativeQueryEditor extends Component { setParameterValue={setParameterValue} syncQueryString isQB + commitImmediately /> <a className="Query-label no-decoration flex-align-right flex align-center px2" onClick={this.toggleEditor}> <span className="mx2">{toggleEditorText}</span> diff --git a/frontend/src/metabase/query_builder/components/QueryVisualization.jsx b/frontend/src/metabase/query_builder/components/QueryVisualization.jsx index 5cdc602c9e48f5dcd5576eb669e6c44c0b2c5a93..24de6c48ff432f55a5aa30b1f931b82a1d213df8 100644 --- a/frontend/src/metabase/query_builder/components/QueryVisualization.jsx +++ b/frontend/src/metabase/query_builder/components/QueryVisualization.jsx @@ -116,10 +116,10 @@ export default class QueryVisualization extends Component { const isEmbeddingEnabled = MetabaseSettings.get("embedding"); return ( <div className="relative flex align-center flex-no-shrink mt2 mb1" style={{ minHeight: "2em" }}> - <div className="z4 flex-full"> + <div className="z4 flex-full hide sm-show"> { !isObjectDetail && <VisualizationSettings ref="settings" {...this.props} /> } </div> - <div className="z3"> + <div className="z3 full"> <Tooltip tooltip={runButtonTooltip}> <RunButton isRunnable={isRunnable} @@ -151,7 +151,7 @@ export default class QueryVisualization extends Component { } { !isResultDirty && result && !result.error ? <QueryDownloadWidget - className="mx1" + className="mx1 hide sm-show" card={card} result={result} /> @@ -161,7 +161,7 @@ export default class QueryVisualization extends Component { (isEmbeddingEnabled && isAdmin) ) ? <QuestionEmbedWidget - className="mx1" + className="mx1 hide sm-show" card={card} /> : null } diff --git a/frontend/src/metabase/query_builder/components/RunButton.jsx b/frontend/src/metabase/query_builder/components/RunButton.jsx index 91ecceca4a1fa6e6aa8bbe22c18e1ce605246ff7..42853ee10ee46309da3ae86aa4a342803d2a4441 100644 --- a/frontend/src/metabase/query_builder/components/RunButton.jsx +++ b/frontend/src/metabase/query_builder/components/RunButton.jsx @@ -25,7 +25,7 @@ export default class RunButton extends Component { buttonText = <div className="flex align-center"><Icon className="mr1" name="refresh" />Refresh</div>; } let actionFn = isRunning ? onCancel : onRun; - let classes = cx("Button Button--medium circular RunButton", { + let classes = cx("Button Button--medium circular RunButton ml-auto mr-auto block", { "RunButton--hidden": !buttonText, "Button--primary": isDirty, "text-grey-2": !isDirty, diff --git a/frontend/src/metabase/query_builder/containers/QueryBuilder.jsx b/frontend/src/metabase/query_builder/containers/QueryBuilder.jsx index d934891be8cb6a19b532b1d3611cda766ee24d69..0a51cc4f03de6fac8e7ed6d5a139fbeea7883ca4 100644 --- a/frontend/src/metabase/query_builder/containers/QueryBuilder.jsx +++ b/frontend/src/metabase/query_builder/containers/QueryBuilder.jsx @@ -1,6 +1,7 @@ import React, { Component } from "react"; import ReactDOM from "react-dom"; import { connect } from "react-redux"; + import cx from "classnames"; import _ from "underscore"; @@ -18,6 +19,8 @@ import TagEditorSidebar from "../components/template_tags/TagEditorSidebar.jsx"; import SavedQuestionIntroModal from "../components/SavedQuestionIntroModal.jsx"; import ActionsWidget from "../components/ActionsWidget.jsx"; +import title from "metabase/hoc/Title"; + import { getCard, getOriginalCard, @@ -123,6 +126,7 @@ const mapDispatchToProps = { }; @connect(mapStateToProps, mapDispatchToProps) +@title(({ card }) => (card && card.name) || "Question") export default class QueryBuilder extends Component { constructor(props, context) { @@ -215,7 +219,7 @@ class LegacyQueryBuilder extends Component { <QueryHeader {...this.props}/> </div> - <div id="react_qb_editor" className="z2"> + <div id="react_qb_editor" className="z2 hide sm-show"> { card && card.dataset_query && card.dataset_query.type === "native" ? <NativeQueryEditor {...this.props} @@ -241,7 +245,7 @@ class LegacyQueryBuilder extends Component { } </div> - <div className={cx("SideDrawer", { "SideDrawer--show": showDrawer })}> + <div className={cx("SideDrawer hide sm-show", { "SideDrawer--show": showDrawer })}> { uiControls.isShowingDataReference && <DataReference {...this.props} onClose={() => this.props.toggleDataReference()} /> } diff --git a/frontend/src/metabase/questions/containers/CollectionPage.jsx b/frontend/src/metabase/questions/containers/CollectionPage.jsx index c69b15be2244a3fd6a3394eeaf68a405e4f03789..49822508801a6e045b1436d90cb7b8b7aa3623fd 100644 --- a/frontend/src/metabase/questions/containers/CollectionPage.jsx +++ b/frontend/src/metabase/questions/containers/CollectionPage.jsx @@ -1,6 +1,7 @@ import React, { Component } from "react"; import { connect } from "react-redux"; import { push, replace, goBack } from "react-router-redux"; +import title from "metabase/hoc/Title"; import Icon from "metabase/components/Icon"; import HeaderWithBack from "metabase/components/HeaderWithBack"; @@ -27,6 +28,7 @@ const mapDispatchToProps = ({ }) @connect(mapStateToProps, mapDispatchToProps) +@title(({ collection }) => collection && collection.name) export default class CollectionPage extends Component { componentWillMount () { this.props.loadCollections(); diff --git a/frontend/src/metabase/redux/user.js b/frontend/src/metabase/redux/user.js index d0c7bcd27cc20ef2dc6b072aae7b446fa4d2e293..071a08cd4611c9c1165385fdb5492298a96667e7 100644 --- a/frontend/src/metabase/redux/user.js +++ b/frontend/src/metabase/redux/user.js @@ -3,10 +3,12 @@ import { createAction, handleActions, createThunkAction } from "metabase/lib/redux"; import { CLOSE_QB_NEWB_MODAL } from "metabase/query_builder/actions"; +import { LOGOUT } from "metabase/auth/auth"; import { UserApi } from "metabase/services"; -export const refreshCurrentUser = createAction("REFRESH_CURRENT_USER", () => { +export const REFRESH_CURRENT_USER = "metabase/user/REFRESH_CURRENT_USER"; +export const refreshCurrentUser = createAction(REFRESH_CURRENT_USER, () => { try { return UserApi.current(); } catch (e) { @@ -14,7 +16,8 @@ export const refreshCurrentUser = createAction("REFRESH_CURRENT_USER", () => { } }); -export const loadCurrentUser = createThunkAction("LOAD_CURRENT_USER", () => +export const LOAD_CURRENT_USER = "metabase/user/LOAD_CURRENT_USER"; +export const loadCurrentUser = createThunkAction(LOAD_CURRENT_USER, () => async (dispatch, getState) => { if (!getState().currentUser) { await dispatch(refreshCurrentUser()); @@ -22,8 +25,12 @@ export const loadCurrentUser = createThunkAction("LOAD_CURRENT_USER", () => } ) +export const CLEAR_CURRENT_USER = "metabase/user/CLEAR_CURRENT_USER" +export const clearCurrentUser = createAction(CLEAR_CURRENT_USER) + export const currentUser = handleActions({ - ["REFRESH_CURRENT_USER"]: { next: (state, { payload }) => payload }, - ["AUTH_LOGOUT"]: { next: (state, { payload }) => null }, + [LOGOUT]: { next: (state, { payload }) => null }, + [CLEAR_CURRENT_USER]: { next: (state, payload) => null }, + [REFRESH_CURRENT_USER]: { next: (state, { payload }) => payload }, [CLOSE_QB_NEWB_MODAL]: { next: (state, { payload }) => ({ ...state, is_qbnewb: false }) }, }, null); diff --git a/frontend/src/metabase/routes.jsx b/frontend/src/metabase/routes.jsx index baf9b7f9987a631c51748cfc7b8f3da4fb00e6cf..fc9ae811192016a2a0cbb2a8721b1697569c09ca 100644 --- a/frontend/src/metabase/routes.jsx +++ b/frontend/src/metabase/routes.jsx @@ -2,7 +2,8 @@ import React from "react"; -import { Route, Redirect, IndexRedirect, IndexRoute } from 'react-router'; +import { Route } from "metabase/hoc/Title"; +import { Redirect, IndexRedirect, IndexRoute } from 'react-router'; import { routerActions } from 'react-router-redux'; import { UserAuthWrapper } from 'redux-auth-wrapper'; @@ -115,7 +116,7 @@ const IsAdmin = MetabaseIsSetup(UserIsAuthenticated(UserIsAdmin(({ children }) = const IsNotAuthenticated = MetabaseIsSetup(UserIsNotAuthenticated(({ children }) => children)); export const getRoutes = (store) => - <Route component={App}> + <Route title="Metabase" component={App}> {/* SETUP */} <Route path="/setup" component={SetupApp} onEnter={(nextState, replace) => { if (!MetabaseSettings.hasSetupToken()) { @@ -138,7 +139,7 @@ export const getRoutes = (store) => <Route path="/auth"> <IndexRedirect to="/auth/login" /> <Route component={IsNotAuthenticated}> - <Route path="login" component={LoginApp} /> + <Route path="login" title="Login" component={LoginApp} /> </Route> <Route path="logout" component={LogoutApp} /> <Route path="forgot_password" component={ForgotPasswordApp} /> @@ -152,17 +153,17 @@ export const getRoutes = (store) => <Route path="/" component={HomepageApp} /> {/* DASHBOARD */} - <Route path="/dashboard/:dashboardId" component={DashboardApp} /> + <Route path="/dashboard/:dashboardId" title="Dashboard" component={DashboardApp} /> {/* QUERY BUILDER */} <Route path="/question" component={QueryBuilder} /> <Route path="/question/:cardId" component={QueryBuilder} /> {/* QUESTIONS */} - <Route path="/questions"> + <Route path="/questions" title="Questions"> <IndexRoute component={QuestionIndex} /> - <Route path="search" component={SearchResults} /> - <Route path="archive" component={Archive} /> + <Route path="search" title={({ location: { query: { q } }}) => "Search: " + q} component={SearchResults} /> + <Route path="archive" title="Archive" component={Archive} /> <Route path="collections/:collectionSlug" component={CollectionPage} /> </Route> @@ -183,9 +184,9 @@ export const getRoutes = (store) => </Route> {/* REFERENCE */} - <Route path="/reference" component={ReferenceApp}> + <Route path="/reference" title="Data Reference" component={ReferenceApp}> <IndexRedirect to="/reference/guide" /> - <Route path="guide" component={ReferenceGettingStartedGuide} /> + <Route path="guide" title="Getting Started" component={ReferenceGettingStartedGuide} /> <Route path="metrics" component={ReferenceEntityList} /> <Route path="metrics/:metricId" component={ReferenceEntity} /> <Route path="metrics/:metricId/questions" component={ReferenceEntityList} /> @@ -206,23 +207,27 @@ export const getRoutes = (store) => </Route> {/* PULSE */} - <Route path="/pulse" component={PulseListApp} /> - <Route path="/pulse/create" component={PulseEditApp} /> - <Route path="/pulse/:pulseId" component={PulseEditApp} /> + <Route path="/pulse" title="Pulses"> + <IndexRoute component={PulseListApp} /> + <Route path="create" component={PulseEditApp} /> + <Route path=":pulseId" component={PulseEditApp} /> + </Route> {/* USER */} <Route path="/user/edit_current" component={UserSettingsApp} /> </Route> {/* ADMIN */} - <Route path="/admin" component={IsAdmin}> + <Route path="/admin" title="Admin" component={IsAdmin}> <IndexRedirect to="/admin/settings" /> - <Route path="databases" component={DatabaseListApp} /> - <Route path="databases/create" component={DatabaseEditApp} /> - <Route path="databases/:databaseId" component={DatabaseEditApp} /> + <Route path="databases" title="Databases"> + <IndexRoute component={DatabaseListApp} /> + <Route path="create" component={DatabaseEditApp} /> + <Route path=":databaseId" component={DatabaseEditApp} /> + </Route> - <Route path="datamodel"> + <Route path="datamodel" title="Data Model"> <IndexRedirect to="database" /> <Route path="database" component={MetadataEditorApp} /> <Route path="database/:databaseId" component={MetadataEditorApp} /> @@ -236,16 +241,20 @@ export const getRoutes = (store) => </Route> {/* PEOPLE */} - <Route path="people" component={AdminPeopleApp}> + <Route path="people" title="People" component={AdminPeopleApp}> <IndexRoute component={PeopleListingApp} /> - <Route path="groups"> + <Route path="groups" title="Groups"> <IndexRoute component={GroupsListingApp} /> <Route path=":groupId" component={GroupDetailApp} /> </Route> </Route> - <Route path="settings" component={SettingsEditorApp} /> - <Route path="settings/:section" component={SettingsEditorApp} /> + {/* SETTINGS */} + <Route path="settings" title="Settings"> + <IndexRedirect to="/admin/settings/setup" /> + {/* <IndexRoute component={SettingsEditorApp} /> */} + <Route path=":section" component={SettingsEditorApp} /> + </Route> {getAdminPermissionsRoutes(store)} </Route> @@ -256,11 +265,10 @@ export const getRoutes = (store) => getChildRoutes={(partialNextState, callback) => // $FlowFixMe: flow doesn't know about require.ensure require.ensure([], (require) => { - callback(null, [require('./routes-internal').default]) + callback(null, [require("metabase/internal/routes").default]) }) } > - <IndexRedirect to="/_internal/list" /> </Route> {/* DEPRECATED */} diff --git a/frontend/src/metabase/visualizations/visualizations/Funnel.jsx b/frontend/src/metabase/visualizations/visualizations/Funnel.jsx index 63548400bce173fa9bd746be11c830322c8ae069..ab15739464b8828ff35ce45aeef0c7671bc0a3c5 100644 --- a/frontend/src/metabase/visualizations/visualizations/Funnel.jsx +++ b/frontend/src/metabase/visualizations/visualizations/Funnel.jsx @@ -51,14 +51,14 @@ export default class Funnel extends Component<*, VisualizationProps, *> { "funnel.dimension": { section: "Data", title: "Step", - ...dimensionSetting("pie.dimension"), + ...dimensionSetting("funnel.dimension"), dashboard: false, useRawSeries: true, }, "funnel.metric": { section: "Data", title: "Measure", - ...metricSetting("pie.metric"), + ...metricSetting("funnel.metric"), dashboard: false, useRawSeries: true, }, diff --git a/frontend/stories/CheckBox.js b/frontend/stories/CheckBox.js deleted file mode 100644 index 129f19a082de7665dd5cff4279085d053a5701c8..0000000000000000000000000000000000000000 --- a/frontend/stories/CheckBox.js +++ /dev/null @@ -1,14 +0,0 @@ -import { React, Centered, storiesOf, action, linkTo } from "."; - -import CheckBox from "metabase/components/CheckBox.jsx"; - -storiesOf("CheckBox", module) - .add("on inverted", () => - <Centered><CheckBox style={{ color: "#509EE3" }} invertChecked checked={true} onChange={linkTo("CheckBox", "off")} /></Centered> - ) - .add("off", () => - <Centered><CheckBox checked={false} onChange={linkTo("CheckBox", "on inverted")} /></Centered> - ) - .add("on", () => - <Centered><CheckBox checked={true} onChange={action("onChange")} /></Centered> - ) diff --git a/frontend/stories/StackedCheckBox.js b/frontend/stories/StackedCheckBox.js deleted file mode 100644 index 3c92a814496461e128aad399cadbcc32f0d644cc..0000000000000000000000000000000000000000 --- a/frontend/stories/StackedCheckBox.js +++ /dev/null @@ -1,14 +0,0 @@ -import { React, Centered, storiesOf, action, linkTo } from "."; - -import StackedCheckBox from "metabase/components/StackedCheckBox.jsx"; - -storiesOf("StackedCheckBox", module) - .add("on inverted", () => - <Centered><StackedCheckBox style={{ color: "#509EE3" }} invertChecked checked={true} onChange={linkTo("StackedCheckBox", "off")} /></Centered> - ) - .add("off", () => - <Centered><StackedCheckBox checked={false} onChange={linkTo("StackedCheckBox", "on inverted")} /></Centered> - ) - .add("on", () => - <Centered><StackedCheckBox checked={true} onChange={action("onChange")} /></Centered> - ) diff --git a/frontend/stories/Toggle.js b/frontend/stories/Toggle.js deleted file mode 100644 index fcb38631f7e8a3db22bb02bf07b6ae3ea3f0f4ac..0000000000000000000000000000000000000000 --- a/frontend/stories/Toggle.js +++ /dev/null @@ -1,11 +0,0 @@ -import { React, Centered, storiesOf, action, linkTo } from "."; - -import Toggle from "metabase/components/Toggle.jsx"; - -storiesOf("Toggle", module) - .add("on", () => - <Centered><Toggle value={true} onChange={linkTo("Toggle", "off")} /></Centered> - ) - .add("off", () => - <Centered><Toggle value={false} onChange={linkTo("Toggle", "on")} /></Centered> - ) diff --git a/frontend/stories/index.js b/frontend/stories/index.js deleted file mode 100644 index a5ea5013e71dba5a90300253f7da0915e090cd63..0000000000000000000000000000000000000000 --- a/frontend/stories/index.js +++ /dev/null @@ -1,21 +0,0 @@ - -// import all modules in this directory (http://stackoverflow.com/a/31770875) -var req = require.context("./", true, /^(.*\.(js$))[^.]*$/igm); -req.keys().forEach(function(key){ - req(key); -}); - -import React from "react"; - -// helper to center a component within the viewport -export const Centered = ({ children }) => - <div style={{ height: "100vh", display: "flex", alignItems: "center", justifyContent: "center" }}> - {children} - </div> - -// re-export commonly used APIs for convienence, e.x. -// -// import { React, Centered, storiesOf, action } from "."; -// -export { storiesOf, action, linkTo } from "@kadira/storybook"; -export React from "react"; diff --git a/frontend/test/__mocks__/fileMock.js b/frontend/test/__mocks__/fileMock.js new file mode 100644 index 0000000000000000000000000000000000000000..86059f36292497436f0fdbd0fb673f6ea9535159 --- /dev/null +++ b/frontend/test/__mocks__/fileMock.js @@ -0,0 +1 @@ +module.exports = 'test-file-stub'; diff --git a/frontend/test/__mocks__/styleMock.js b/frontend/test/__mocks__/styleMock.js new file mode 100644 index 0000000000000000000000000000000000000000..f053ebf7976e3726d11f3c03fade2170903889a5 --- /dev/null +++ b/frontend/test/__mocks__/styleMock.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/package.json b/package.json index 079300b233224a4725917213d962277c6c0fc2d1..b07ff71f4f4fe9d08d6e5d86ec55bcd12cf27e4a 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "react-copy-to-clipboard": "^4.2.3", "react-dom": "15.5.0", "react-draggable": "^2.2.3", + "react-element-to-jsx-string": "^6.3.0", "react-height": "^2.1.1", "react-motion": "^0.4.5", "react-redux": "^5.0.1", @@ -72,7 +73,6 @@ "z-index": "0.0.1" }, "devDependencies": { - "@kadira/storybook": "^2.35.2", "@slack/client": "^3.5.4", "babel-cli": "^6.11.4", "babel-core": "^6.20.0", @@ -105,7 +105,6 @@ "glob": "^7.1.1", "html-webpack-harddisk-plugin": "^0.1.0", "html-webpack-plugin": "^2.14.0", - "husky": "^0.13.2", "image-diff": "^1.6.3", "imports-loader": "^0.7.0", "jasmine": "^2.4.1", @@ -157,7 +156,6 @@ "build-watch": "webpack --watch", "build-hot": "NODE_ENV=hot webpack-dev-server --progress", "start": "yarn run build && lein ring server", - "storybook": "start-storybook -p 9001", "precommit": "lint-staged", "preinstall": "echo $npm_execpath | grep -q yarn || echo '\\033[0;33mSorry, npm is not supported. Please use Yarn (https://yarnpkg.com/).\\033[0m'", "prettier": "prettier --tab-width 4 --write 'frontend/src/metabase/qb/**/*.js*' 'frontend/src/metabase/new_question/**/*.js*'", @@ -179,6 +177,10 @@ ], "modulePaths": [ "<rootDir>/frontend/src" - ] + ], + "moduleNameMapper": { + "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js", + "\\.(css|less)$": "<rootDir>/frontend/test/__mocks__/styleMock.js" + } } } diff --git a/resources/migrations/000_migrations.yaml b/resources/migrations/000_migrations.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6204cdf0f5bf3ad58e8a88b06e6b2ec8a7e97ba6 --- /dev/null +++ b/resources/migrations/000_migrations.yaml @@ -0,0 +1,3583 @@ +databaseChangeLog: + - changeSet: + id: '1' + author: agilliland + changes: + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + unique: true + name: slug + type: varchar(254) + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + name: description + type: text + - column: + name: logo_url + type: varchar(254) + - column: + constraints: + nullable: false + name: inherits + type: boolean + tableName: core_organization + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + unique: true + name: email + type: varchar(254) + - column: + constraints: + nullable: false + name: first_name + type: varchar(254) + - column: + constraints: + nullable: false + name: last_name + type: varchar(254) + - column: + constraints: + nullable: false + name: password + type: varchar(254) + - column: + constraints: + nullable: false + defaultValue: default + name: password_salt + type: varchar(254) + - column: + constraints: + nullable: false + name: date_joined + type: DATETIME + - column: + constraints: + nullable: true + name: last_login + type: DATETIME + - column: + constraints: + nullable: false + name: is_staff + type: boolean + - column: + constraints: + nullable: false + name: is_superuser + type: boolean + - column: + constraints: + nullable: false + name: is_active + type: boolean + - column: + name: reset_token + type: varchar(254) + - column: + name: reset_triggered + type: BIGINT + tableName: core_user + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: admin + type: boolean + - column: + constraints: + deferrable: false + foreignKeyName: fk_userorgperm_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: user_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_userorgperm_ref_organization_id + initiallyDeferred: false + nullable: false + references: core_organization(id) + name: organization_id + type: int + tableName: core_userorgperm + - addUniqueConstraint: + columnNames: user_id, organization_id + constraintName: idx_unique_user_id_organization_id + tableName: core_userorgperm + - createIndex: + columns: + - column: + name: user_id + type: int + indexName: idx_userorgperm_user_id + tableName: core_userorgperm + - createIndex: + columns: + - column: + name: organization_id + type: int + indexName: idx_userorgperm_organization_id + tableName: core_userorgperm + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: url + type: varchar(254) + - column: + constraints: + nullable: false + name: timestamp + type: DATETIME + - column: + constraints: + deferrable: false + foreignKeyName: fk_permissionviolation_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: user_id + type: int + tableName: core_permissionsviolation + - createIndex: + columns: + - column: + name: user_id + type: int + indexName: idx_permissionsviolation_user_id + tableName: core_permissionsviolation + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + name: description + type: text + - column: + constraints: + deferrable: false + foreignKeyName: fk_database_ref_organization_id + initiallyDeferred: false + nullable: false + references: core_organization(id) + name: organization_id + type: int + - column: + name: details + type: text + - column: + constraints: + nullable: false + name: engine + type: varchar(254) + tableName: metabase_database + - createIndex: + columns: + - column: + name: organization_id + indexName: idx_database_organization_id + tableName: metabase_database + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + name: rows + type: int + - column: + name: description + type: text + - column: + name: entity_name + type: varchar(254) + - column: + name: entity_type + type: varchar(254) + - column: + constraints: + nullable: false + name: active + type: boolean + - column: + constraints: + deferrable: false + foreignKeyName: fk_table_ref_database_id + initiallyDeferred: false + nullable: false + references: metabase_database(id) + name: db_id + type: int + tableName: metabase_table + - createIndex: + columns: + - column: + name: db_id + indexName: idx_table_db_id + tableName: metabase_table + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + constraints: + nullable: false + name: base_type + type: varchar(255) + - column: + name: special_type + type: varchar(255) + - column: + constraints: + nullable: false + name: active + type: boolean + - column: + name: description + type: text + - column: + constraints: + nullable: false + name: preview_display + type: boolean + - column: + constraints: + nullable: false + name: position + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_field_ref_table_id + initiallyDeferred: false + nullable: false + references: metabase_table(id) + name: table_id + type: int + - column: + constraints: + nullable: false + name: field_type + type: varchar(254) + tableName: metabase_field + - createIndex: + columns: + - column: + name: table_id + indexName: idx_field_table_id + tableName: metabase_field + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: relationship + type: varchar(254) + - column: + constraints: + deferrable: false + foreignKeyName: fk_foreignkey_dest_ref_field_id + initiallyDeferred: false + nullable: false + references: metabase_field(id) + name: destination_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_foreignkey_origin_ref_field_id + initiallyDeferred: false + nullable: false + references: metabase_field(id) + name: origin_id + type: int + tableName: metabase_foreignkey + - createIndex: + columns: + - column: + name: destination_id + indexName: idx_foreignkey_destination_id + tableName: metabase_foreignkey + - createIndex: + columns: + - column: + name: origin_id + indexName: idx_foreignkey_origin_id + tableName: metabase_foreignkey + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + name: values + type: text + - column: + name: human_readable_values + type: text + - column: + constraints: + deferrable: false + foreignKeyName: fk_fieldvalues_ref_field_id + initiallyDeferred: false + nullable: false + references: metabase_field(id) + name: field_id + type: int + tableName: metabase_fieldvalues + - createIndex: + columns: + - column: + name: field_id + indexName: idx_fieldvalues_field_id + tableName: metabase_fieldvalues + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + constraints: + deferrable: false + foreignKeyName: fk_tablesegment_ref_table_id + initiallyDeferred: false + nullable: false + references: metabase_table(id) + name: table_id + type: int + - column: + constraints: + nullable: false + name: filter_clause + type: text + tableName: metabase_tablesegment + - createIndex: + columns: + - column: + name: table_id + indexName: idx_tablesegment_table_id + tableName: metabase_tablesegment + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + constraints: + nullable: false + name: type + type: varchar(254) + - column: + constraints: + nullable: false + name: details + type: text + - column: + constraints: + nullable: false + name: version + type: int + - column: + constraints: + nullable: false + name: public_perms + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_query_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: creator_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_query_ref_database_id + initiallyDeferred: false + nullable: false + references: metabase_database(id) + name: database_id + type: int + tableName: query_query + - createIndex: + columns: + - column: + name: creator_id + indexName: idx_query_creator_id + tableName: query_query + - createIndex: + columns: + - column: + name: database_id + indexName: idx_query_database_id + tableName: query_query + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + unique: true + name: uuid + type: varchar(254) + - column: + constraints: + nullable: false + name: version + type: int + - column: + constraints: + nullable: false + name: json_query + type: text + - column: + constraints: + nullable: false + name: raw_query + type: text + - column: + constraints: + nullable: false + name: status + type: varchar(254) + - column: + constraints: + nullable: false + name: started_at + type: DATETIME + - column: + name: finished_at + type: DATETIME + - column: + constraints: + nullable: false + name: running_time + type: int + - column: + constraints: + nullable: false + name: error + type: text + - column: + constraints: + nullable: false + name: result_file + type: varchar(254) + - column: + constraints: + nullable: false + name: result_rows + type: int + - column: + constraints: + nullable: false + name: result_data + type: text + - column: + constraints: + deferrable: false + foreignKeyName: fk_queryexecution_ref_query_id + initiallyDeferred: false + nullable: true + references: query_query(id) + name: query_id + type: int + - column: + constraints: + nullable: false + name: additional_info + type: text + - column: + constraints: + deferrable: false + foreignKeyName: fk_queryexecution_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: executor_id + type: int + tableName: query_queryexecution + - createIndex: + columns: + - column: + name: query_id + indexName: idx_queryexecution_query_id + tableName: query_queryexecution + - createIndex: + columns: + - column: + name: executor_id + indexName: idx_queryexecution_executor_id + tableName: query_queryexecution + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + name: description + type: text + - column: + constraints: + nullable: false + name: display + type: varchar(254) + - column: + constraints: + nullable: false + name: public_perms + type: int + - column: + constraints: + nullable: false + name: dataset_query + type: text + - column: + constraints: + nullable: false + name: visualization_settings + type: text + - column: + constraints: + deferrable: false + foreignKeyName: fk_card_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: creator_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_card_ref_organization_id + initiallyDeferred: false + nullable: false + references: core_organization(id) + name: organization_id + type: int + tableName: report_card + - createIndex: + columns: + - column: + name: creator_id + indexName: idx_card_creator_id + tableName: report_card + - createIndex: + columns: + - column: + name: organization_id + indexName: idx_card_organization_id + tableName: report_card + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + deferrable: false + foreignKeyName: fk_cardfavorite_ref_card_id + initiallyDeferred: false + nullable: false + references: report_card(id) + name: card_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_cardfavorite_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: owner_id + type: int + tableName: report_cardfavorite + - addUniqueConstraint: + columnNames: card_id, owner_id + constraintName: idx_unique_cardfavorite_card_id_owner_id + tableName: report_cardfavorite + - createIndex: + columns: + - column: + name: card_id + indexName: idx_cardfavorite_card_id + tableName: report_cardfavorite + - createIndex: + columns: + - column: + name: owner_id + indexName: idx_cardfavorite_owner_id + tableName: report_cardfavorite + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + name: description + type: text + - column: + constraints: + nullable: false + name: public_perms + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_dashboard_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: creator_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_dashboard_ref_organization_id + initiallyDeferred: false + nullable: false + references: core_organization(id) + name: organization_id + type: int + tableName: report_dashboard + - createIndex: + columns: + - column: + name: creator_id + indexName: idx_dashboard_creator_id + tableName: report_dashboard + - createIndex: + columns: + - column: + name: organization_id + indexName: idx_dashboard_organization_id + tableName: report_dashboard + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: sizeX + type: int + - column: + constraints: + nullable: false + name: sizeY + type: int + - column: + name: row + type: int + - column: + name: col + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_dashboardcard_ref_card_id + initiallyDeferred: false + nullable: false + references: report_card(id) + name: card_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_dashboardcard_ref_dashboard_id + initiallyDeferred: false + nullable: false + references: report_dashboard(id) + name: dashboard_id + type: int + tableName: report_dashboardcard + - createIndex: + columns: + - column: + name: card_id + indexName: idx_dashboardcard_card_id + tableName: report_dashboardcard + - createIndex: + columns: + - column: + name: dashboard_id + indexName: idx_dashboardcard_dashboard_id + tableName: report_dashboardcard + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_dashboardsubscription_ref_dashboard_id + initiallyDeferred: false + nullable: false + references: report_dashboard(id) + name: dashboard_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_dashboardsubscription_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: user_id + type: int + tableName: report_dashboardsubscription + - addUniqueConstraint: + columnNames: dashboard_id, user_id + constraintName: idx_uniq_dashsubscrip_dashboard_id_user_id + tableName: report_dashboardsubscription + - createIndex: + columns: + - column: + name: dashboard_id + indexName: idx_dashboardsubscription_dashboard_id + tableName: report_dashboardsubscription + - createIndex: + columns: + - column: + name: user_id + indexName: idx_dashboardsubscription_user_id + tableName: report_dashboardsubscription + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: name + type: varchar(254) + - column: + name: description + type: text + - column: + constraints: + nullable: false + name: public_perms + type: int + - column: + constraints: + nullable: false + name: mode + type: int + - column: + constraints: + nullable: false + name: version + type: int + - column: + constraints: + nullable: false + name: dataset_query + type: text + - column: + name: email_addresses + type: text + - column: + constraints: + deferrable: false + foreignKeyName: fk_emailreport_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: creator_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_emailreport_ref_organization_id + initiallyDeferred: false + nullable: false + references: core_organization(id) + name: organization_id + type: int + - column: + constraints: + nullable: false + name: schedule + type: text + tableName: report_emailreport + - createIndex: + columns: + - column: + name: creator_id + indexName: idx_emailreport_creator_id + tableName: report_emailreport + - createIndex: + columns: + - column: + name: organization_id + indexName: idx_emailreport_organization_id + tableName: report_emailreport + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_emailreport_recipients_ref_emailreport_id + initiallyDeferred: false + nullable: false + references: report_emailreport(id) + name: emailreport_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_emailreport_recipients_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: user_id + type: int + tableName: report_emailreport_recipients + - addUniqueConstraint: + columnNames: emailreport_id, user_id + constraintName: idx_uniq_emailreportrecip_emailreport_id_user_id + tableName: report_emailreport_recipients + - createIndex: + columns: + - column: + name: emailreport_id + indexName: idx_emailreport_recipients_emailreport_id + tableName: report_emailreport_recipients + - createIndex: + columns: + - column: + name: user_id + indexName: idx_emailreport_recipients_user_id + tableName: report_emailreport_recipients + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: details + type: text + - column: + constraints: + nullable: false + name: status + type: varchar(254) + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + name: started_at + type: DATETIME + - column: + name: finished_at + type: DATETIME + - column: + constraints: + nullable: false + name: error + type: text + - column: + constraints: + nullable: false + name: sent_email + type: text + - column: + constraints: + deferrable: false + foreignKeyName: fk_emailreportexecutions_ref_organization_id + initiallyDeferred: false + nullable: false + references: core_organization(id) + name: organization_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_emailreportexecutions_ref_report_id + initiallyDeferred: false + nullable: true + references: report_emailreport(id) + name: report_id + type: int + tableName: report_emailreportexecutions + - createIndex: + columns: + - column: + name: organization_id + indexName: idx_emailreportexecutions_organization_id + tableName: report_emailreportexecutions + - createIndex: + columns: + - column: + name: report_id + indexName: idx_emailreportexecutions_report_id + tableName: report_emailreportexecutions + - createTable: + columns: + - column: + autoIncrement: true + constraints: + nullable: false + primaryKey: true + name: id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + - column: + constraints: + nullable: false + name: updated_at + type: DATETIME + - column: + constraints: + nullable: false + name: start + type: DATETIME + - column: + constraints: + nullable: false + name: end + type: DATETIME + - column: + name: title + type: TEXT + - column: + constraints: + nullable: false + name: body + type: TEXT + - column: + constraints: + nullable: false + name: annotation_type + type: int + - column: + constraints: + nullable: false + name: edit_count + type: int + - column: + constraints: + nullable: false + name: object_type_id + type: int + - column: + constraints: + nullable: false + name: object_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_annotation_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: author_id + type: int + - column: + constraints: + deferrable: false + foreignKeyName: fk_annotation_ref_organization_id + initiallyDeferred: false + nullable: false + references: core_organization(id) + name: organization_id + type: int + tableName: annotation_annotation + - createIndex: + columns: + - column: + name: author_id + indexName: idx_annotation_author_id + tableName: annotation_annotation + - createIndex: + columns: + - column: + name: organization_id + indexName: idx_annotation_organization_id + tableName: annotation_annotation + - createIndex: + columns: + - column: + name: object_type_id + indexName: idx_annotation_object_type_id + tableName: annotation_annotation + - createIndex: + columns: + - column: + name: object_id + indexName: idx_annotation_object_id + tableName: annotation_annotation + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: '2' + author: agilliland + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + primaryKey: true + name: id + type: varchar(254) + - column: + constraints: + deferrable: false + foreignKeyName: fk_session_ref_user_id + initiallyDeferred: false + nullable: false + references: core_user(id) + name: user_id + type: int + - column: + constraints: + nullable: false + name: created_at + type: DATETIME + tableName: core_session + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: '4' + author: cammsaul + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + primaryKey: true + name: key + type: varchar(254) + - column: + constraints: + nullable: false + name: value + type: varchar(254) + tableName: setting + - changeSet: + id: '5' + author: agilliland + changes: + - addColumn: + columns: + - column: + name: report_timezone + type: varchar(254) + tableName: core_organization + - changeSet: + id: '6' + author: agilliland + changes: + - dropNotNullConstraint: + columnDataType: int + columnName: organization_id + tableName: metabase_database + - dropForeignKeyConstraint: + baseTableName: metabase_database + constraintName: fk_database_ref_organization_id + - dropNotNullConstraint: + columnDataType: int + columnName: organization_id + tableName: report_card + - dropForeignKeyConstraint: + baseTableName: report_card + constraintName: fk_card_ref_organization_id + - dropNotNullConstraint: + columnDataType: int + columnName: organization_id + tableName: report_dashboard + - dropForeignKeyConstraint: + baseTableName: report_dashboard + constraintName: fk_dashboard_ref_organization_id + - dropNotNullConstraint: + columnDataType: int + columnName: organization_id + tableName: report_emailreport + - dropForeignKeyConstraint: + baseTableName: report_emailreport + constraintName: fk_emailreport_ref_organization_id + - dropNotNullConstraint: + columnDataType: int + columnName: organization_id + tableName: report_emailreportexecutions + - dropForeignKeyConstraint: + baseTableName: report_emailreportexecutions + constraintName: fk_emailreportexecutions_ref_organization_id + - dropNotNullConstraint: + columnDataType: int + columnName: organization_id + tableName: annotation_annotation + - dropForeignKeyConstraint: + baseTableName: annotation_annotation + constraintName: fk_annotation_ref_organization_id + - changeSet: + id: '7' + author: cammsaul + changes: + - addColumn: + columns: + - column: + constraints: + foreignKeyName: fk_field_parent_ref_field_id + nullable: true + references: metabase_field(id) + name: parent_id + type: int + tableName: metabase_field + - changeSet: + id: '8' + author: tlrobinson + changes: + - addColumn: + columns: + - column: + name: display_name + type: varchar(254) + tableName: metabase_table + - addColumn: + columns: + - column: + name: display_name + type: varchar(254) + tableName: metabase_field + - changeSet: + id: '9' + author: tlrobinson + changes: + - addColumn: + columns: + - column: + name: visibility_type + type: varchar(254) + tableName: metabase_table + - changeSet: + id: 10 + author: cammsaul + changes: + - createTable: + tableName: revision + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: model + type: varchar(16) + constraints: + nullable: false + - column: + name: model_id + type: int + constraints: + nullable: false + - column: + name: user_id + type: int + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_revision_ref_user_id + deferrable: false + initiallyDeferred: false + - column: + name: timestamp + type: DATETIME + constraints: + nullable: false + - column: + name: object + type: varchar + constraints: + nullable: false + - column: + name: is_reversion + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - createIndex: + tableName: revision + indexName: idx_revision_model_model_id + columns: + column: + name: model + column: + name: model_id + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - modifySql: + dbms: mysql + replace: + replace: object VARCHAR + with: object TEXT + - changeSet: + id: 11 + author: agilliland + changes: + - sql: + sql: update report_dashboard set public_perms = 2 where public_perms = 1 + - changeSet: + id: 12 + author: agilliland + changes: + - addColumn: + tableName: report_card + columns: + - column: + name: database_id + type: int + constraints: + nullable: true + references: metabase_database(id) + foreignKeyName: fk_report_card_ref_database_id + deferrable: false + initiallyDeferred: false + - column: + name: table_id + type: int + constraints: + nullable: true + references: metabase_table(id) + foreignKeyName: fk_report_card_ref_table_id + deferrable: false + initiallyDeferred: false + - column: + name: query_type + type: varchar(16) + constraints: + nullable: true + - changeSet: + id: 13 + author: agilliland + changes: + - createTable: + tableName: activity + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: topic + type: varchar(32) + constraints: + nullable: false + - column: + name: timestamp + type: DATETIME + constraints: + nullable: false + - column: + name: user_id + type: int + constraints: + nullable: true + references: core_user(id) + foreignKeyName: fk_activity_ref_user_id + deferrable: false + initiallyDeferred: false + - column: + name: model + type: varchar(16) + constraints: + nullable: true + - column: + name: model_id + type: int + constraints: + nullable: true + - column: + name: database_id + type: int + constraints: + nullable: true + - column: + name: table_id + type: int + constraints: + nullable: true + - column: + name: custom_id + type: varchar(48) + constraints: + nullable: true + - column: + name: details + type: varchar + constraints: + nullable: false + - createIndex: + tableName: activity + indexName: idx_activity_timestamp + columns: + column: + name: timestamp + - createIndex: + tableName: activity + indexName: idx_activity_user_id + columns: + column: + name: user_id + - createIndex: + tableName: activity + indexName: idx_activity_custom_id + columns: + column: + name: custom_id + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - modifySql: + dbms: mysql + replace: + replace: details VARCHAR + with: details TEXT + - changeSet: + id: 14 + author: agilliland + changes: + - createTable: + tableName: view_log + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: user_id + type: int + constraints: + nullable: true + references: core_user(id) + foreignKeyName: fk_view_log_ref_user_id + deferrable: false + initiallyDeferred: false + - column: + name: model + type: varchar(16) + constraints: + nullable: false + - column: + name: model_id + type: int + constraints: + nullable: false + - column: + name: timestamp + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: view_log + indexName: idx_view_log_user_id + columns: + column: + name: user_id + - createIndex: + tableName: view_log + indexName: idx_view_log_timestamp + columns: + column: + name: model_id + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 15 + author: agilliland + changes: + - addColumn: + tableName: revision + columns: + - column: + name: is_creation + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - changeSet: + id: 16 + author: agilliland + changes: + - dropNotNullConstraint: + tableName: core_user + columnName: last_login + columnDataType: DATETIME + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 17 + author: agilliland + changes: + - addColumn: + tableName: metabase_database + columns: + - column: + name: is_sample + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - sql: + sql: update metabase_database set is_sample = true where name = 'Sample Dataset' + - changeSet: + id: 18 + author: camsaul + validCheckSum: 7:07d501a6e52c14691f7f895d137e565f + validCheckSum: 7:329d897d44ba9893fdafc9ce7e876d73 + changes: + - createTable: + tableName: data_migrations + columns: + - column: + name: id + type: VARCHAR(254) + constraints: + primaryKey: true + nullable: false + - column: + name: timestamp + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: data_migrations + indexName: idx_data_migrations_id + columns: + column: + name: id + - changeSet: + id: 19 + author: camsaul + changes: + - addColumn: + tableName: metabase_table + columns: + - column: + name: schema + type: VARCHAR(256) + - changeSet: + id: 20 + author: agilliland + changes: + - createTable: + tableName: pulse + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: creator_id + type: int + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_pulse_ref_creator_id + deferrable: false + initiallyDeferred: false + - column: + name: name + type: varchar(254) + constraints: + nullable: false + - column: + name: public_perms + type: int + constraints: + nullable: false + - column: + name: created_at + type: DATETIME + constraints: + nullable: false + - column: + name: updated_at + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: pulse + indexName: idx_pulse_creator_id + columns: + column: + name: creator_id + - createTable: + tableName: pulse_card + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: pulse_id + type: int + constraints: + nullable: false + references: pulse(id) + foreignKeyName: fk_pulse_card_ref_pulse_id + deferrable: false + initiallyDeferred: false + - column: + name: card_id + type: int + constraints: + nullable: false + references: report_card(id) + foreignKeyName: fk_pulse_card_ref_card_id + deferrable: false + initiallyDeferred: false + - column: + name: position + type: int + constraints: + nullable: false + - createIndex: + tableName: pulse_card + indexName: idx_pulse_card_pulse_id + columns: + column: + name: pulse_id + - createIndex: + tableName: pulse_card + indexName: idx_pulse_card_card_id + columns: + column: + name: card_id + - createTable: + tableName: pulse_channel + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: pulse_id + type: int + constraints: + nullable: false + references: pulse(id) + foreignKeyName: fk_pulse_channel_ref_pulse_id + deferrable: false + initiallyDeferred: false + - column: + name: channel_type + type: varchar(32) + constraints: + nullable: false + - column: + name: details + type: text + constraints: + nullable: false + - column: + name: schedule_type + type: varchar(32) + constraints: + nullable: false + - column: + name: schedule_hour + type: int + constraints: + nullable: true + - column: + name: schedule_day + type: varchar(64) + constraints: + nullable: true + - column: + name: created_at + type: DATETIME + constraints: + nullable: false + - column: + name: updated_at + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: pulse_channel + indexName: idx_pulse_channel_pulse_id + columns: + column: + name: pulse_id + - createIndex: + tableName: pulse_channel + indexName: idx_pulse_channel_schedule_type + columns: + column: + name: schedule_type + - createTable: + tableName: pulse_channel_recipient + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: pulse_channel_id + type: int + constraints: + nullable: false + references: pulse_channel(id) + foreignKeyName: fk_pulse_channel_recipient_ref_pulse_channel_id + deferrable: false + initiallyDeferred: false + - column: + name: user_id + type: int + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_pulse_channel_recipient_ref_user_id + deferrable: false + initiallyDeferred: false + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 21 + author: agilliland + changes: + - createTable: + tableName: segment + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: table_id + type: int + constraints: + nullable: false + references: metabase_table(id) + foreignKeyName: fk_segment_ref_table_id + deferrable: false + initiallyDeferred: false + - column: + name: creator_id + type: int + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_segment_ref_creator_id + deferrable: false + initiallyDeferred: false + - column: + name: name + type: varchar(254) + constraints: + nullable: false + - column: + name: description + type: text + constraints: + nullable: true + - column: + name: is_active + type: boolean + defaultValueBoolean: true + constraints: + nullable: false + - column: + name: definition + type: text + constraints: + nullable: false + - column: + name: created_at + type: DATETIME + constraints: + nullable: false + - column: + name: updated_at + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: segment + indexName: idx_segment_creator_id + columns: + column: + name: creator_id + - createIndex: + tableName: segment + indexName: idx_segment_table_id + columns: + column: + name: table_id + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 22 + author: agilliland + changes: + - addColumn: + tableName: revision + columns: + - column: + name: message + type: text + constraints: + nullable: true + - changeSet: + id: 23 + author: agilliland + changes: + - modifyDataType: + tableName: metabase_table + columnName: rows + newDataType: BIGINT + - changeSet: + id: 24 + author: agilliland + changes: + - createTable: + tableName: dependency + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: model + type: varchar(32) + constraints: + nullable: false + - column: + name: model_id + type: int + constraints: + nullable: false + - column: + name: dependent_on_model + type: varchar(32) + constraints: + nullable: false + - column: + name: dependent_on_id + type: int + constraints: + nullable: false + - column: + name: created_at + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: dependency + indexName: idx_dependency_model + columns: + column: + name: model + - createIndex: + tableName: dependency + indexName: idx_dependency_model_id + columns: + column: + name: model_id + - createIndex: + tableName: dependency + indexName: idx_dependency_dependent_on_model + columns: + column: + name: dependent_on_model + - createIndex: + tableName: dependency + indexName: idx_dependency_dependent_on_id + columns: + column: + name: dependent_on_id + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 25 + author: agilliland + changes: + - createTable: + tableName: metric + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: table_id + type: int + constraints: + nullable: false + references: metabase_table(id) + foreignKeyName: fk_metric_ref_table_id + deferrable: false + initiallyDeferred: false + - column: + name: creator_id + type: int + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_metric_ref_creator_id + deferrable: false + initiallyDeferred: false + - column: + name: name + type: varchar(254) + constraints: + nullable: false + - column: + name: description + type: text + constraints: + nullable: true + - column: + name: is_active + type: boolean + defaultValueBoolean: true + constraints: + nullable: false + - column: + name: definition + type: text + constraints: + nullable: false + - column: + name: created_at + type: DATETIME + constraints: + nullable: false + - column: + name: updated_at + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: metric + indexName: idx_metric_creator_id + columns: + column: + name: creator_id + - createIndex: + tableName: metric + indexName: idx_metric_table_id + columns: + column: + name: table_id + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 26 + author: agilliland + changes: + - addColumn: + tableName: metabase_database + columns: + - column: + name: is_full_sync + type: boolean + defaultValueBoolean: true + constraints: + nullable: false + - sql: + sql: update metabase_database set is_full_sync = true + - changeSet: + id: 27 + author: agilliland + changes: + - createTable: + tableName: dashboardcard_series + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: dashboardcard_id + type: int + constraints: + nullable: false + references: report_dashboardcard(id) + foreignKeyName: fk_dashboardcard_series_ref_dashboardcard_id + deferrable: false + initiallyDeferred: false + - column: + name: card_id + type: int + constraints: + nullable: false + references: report_card(id) + foreignKeyName: fk_dashboardcard_series_ref_card_id + deferrable: false + initiallyDeferred: false + - column: + name: position + type: int + constraints: + nullable: false + - createIndex: + tableName: dashboardcard_series + indexName: idx_dashboardcard_series_dashboardcard_id + columns: + column: + name: dashboardcard_id + - createIndex: + tableName: dashboardcard_series + indexName: idx_dashboardcard_series_card_id + columns: + column: + name: card_id + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 28 + author: agilliland + changes: + - addColumn: + tableName: core_user + columns: + - column: + name: is_qbnewb + type: boolean + defaultValueBoolean: true + constraints: + nullable: false + - changeSet: + id: 29 + author: agilliland + changes: + - addColumn: + tableName: pulse_channel + columns: + - column: + name: schedule_frame + type: varchar(32) + constraints: + nullable: true + - changeSet: + id: 30 + author: agilliland + changes: + - addColumn: + tableName: metabase_field + columns: + - column: + name: visibility_type + type: varchar(32) + constraints: + nullable: true + deferrable: false + initiallyDeferred: false + - addNotNullConstraint: + columnDataType: varchar(32) + columnName: visibility_type + defaultNullValue: unset + tableName: metabase_field + - changeSet: + id: 31 + author: agilliland + changes: + - addColumn: + tableName: metabase_field + columns: + - column: + name: fk_target_field_id + type: int + constraints: + nullable: true + deferrable: false + initiallyDeferred: false + - changeSet: + id: 32 + author: camsaul + changes: + ######################################## label table ######################################## + - createTable: + tableName: label + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: name + type: VARCHAR(254) + constraints: + nullable: false + - column: + name: slug + type: VARCHAR(254) + constraints: + nullable: false + unique: true + - column: + name: icon + type: VARCHAR(128) + - createIndex: + tableName: label + indexName: idx_label_slug + columns: + column: + name: slug + ######################################## card_label table ######################################## + - createTable: + tableName: card_label + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: card_id + type: int + constraints: + nullable: false + references: report_card(id) + foreignKeyName: fk_card_label_ref_card_id + deferrable: false + initiallyDeferred: false + - column: + name: label_id + type: int + constraints: + nullable: false + references: label(id) + foreignKeyName: fk_card_label_ref_label_id + deferrable: false + initiallyDeferred: false + - addUniqueConstraint: + tableName: card_label + columnNames: card_id, label_id + constraintName: unique_card_label_card_id_label_id + - createIndex: + tableName: card_label + indexName: idx_card_label_card_id + columns: + column: + name: card_id + - createIndex: + tableName: card_label + indexName: idx_card_label_label_id + columns: + column: + name: label_id + ######################################## add archived column to report_card ######################################## + - addColumn: + tableName: report_card + columns: + - column: + name: archived + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - changeSet: + id: 32 + author: agilliland + changes: + - createTable: + tableName: raw_table + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: database_id + type: int + constraints: + nullable: false + references: metabase_database(id) + foreignKeyName: fk_rawtable_ref_database + deferrable: false + initiallyDeferred: false + - column: + name: active + type: boolean + constraints: + nullable: false + - column: + name: schema + type: varchar(255) + constraints: + nullable: true + - column: + name: name + type: varchar(255) + constraints: + nullable: false + - column: + name: details + type: text + constraints: + nullable: false + - column: + name: created_at + type: DATETIME + constraints: + nullable: false + - column: + name: updated_at + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: raw_table + indexName: idx_rawtable_database_id + columns: + column: + name: database_id + - addUniqueConstraint: + tableName: raw_table + columnNames: database_id, schema, name + constraintName: uniq_raw_table_db_schema_name + - createTable: + tableName: raw_column + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: raw_table_id + type: int + constraints: + nullable: false + references: raw_table(id) + foreignKeyName: fk_rawcolumn_tableid_ref_rawtable + deferrable: false + initiallyDeferred: false + - column: + name: active + type: boolean + constraints: + nullable: false + - column: + name: name + type: varchar(255) + constraints: + nullable: false + - column: + name: column_type + type: varchar(128) + constraints: + nullable: true + - column: + name: is_pk + type: boolean + constraints: + nullable: false + - column: + name: fk_target_column_id + type: int + constraints: + nullable: true + references: raw_column(id) + foreignKeyName: fk_rawcolumn_fktarget_ref_rawcolumn + deferrable: false + initiallyDeferred: false + - column: + name: details + type: text + constraints: + nullable: false + - column: + name: created_at + type: DATETIME + constraints: + nullable: false + - column: + name: updated_at + type: DATETIME + constraints: + nullable: false + - createIndex: + tableName: raw_column + indexName: idx_rawcolumn_raw_table_id + columns: + column: + name: raw_table_id + - addUniqueConstraint: + tableName: raw_column + columnNames: raw_table_id, name + constraintName: uniq_raw_column_table_name + - addColumn: + tableName: metabase_table + columns: + - column: + name: raw_table_id + type: int + constraints: + nullable: true + deferrable: false + initiallyDeferred: false + - addColumn: + tableName: metabase_field + columns: + - column: + name: raw_column_id + type: int + constraints: + nullable: true + deferrable: false + initiallyDeferred: false + - addColumn: + tableName: metabase_field + columns: + - column: + name: last_analyzed + type: DATETIME + constraints: + nullable: true + deferrable: false + initiallyDeferred: false + - modifySql: + dbms: postgresql + replace: + replace: WITHOUT + with: WITH + - changeSet: + id: 34 + author: tlrobinson + changes: + ######################################## add enabled column to pulse_channel ######################################## + - addColumn: + tableName: pulse_channel + columns: + - column: + name: enabled + type: boolean + defaultValueBoolean: true + constraints: + nullable: false + - changeSet: + id: 35 + author: agilliland + changes: + - modifyDataType: + tableName: setting + columnName: value + newDataType: TEXT + - addNotNullContstraint: + tableName: setting + columnNames: value + - changeSet: + id: 36 + author: agilliland + changes: + - addColumn: + tableName: report_dashboard + columns: + - column: + name: parameters + type: text + constraints: + nullable: true + deferrable: false + initiallyDeferred: false + - addNotNullConstraint: + columnDataType: text + columnName: parameters + defaultNullValue: '[]' + tableName: report_dashboard + - addColumn: + tableName: report_dashboardcard + columns: + - column: + name: parameter_mappings + type: text + constraints: + nullable: true + deferrable: false + initiallyDeferred: false + - addNotNullConstraint: + columnDataType: text + columnName: parameter_mappings + defaultNullValue: '[]' + tableName: report_dashboardcard + - changeSet: + id: 37 + author: tlrobinson + changes: + - addColumn: + tableName: query_queryexecution + columns: + - column: + name: query_hash + type: int + constraints: + nullable: true + - addNotNullConstraint: + tableName: query_queryexecution + columnName: query_hash + columnDataType: int + defaultNullValue: 0 + - createIndex: + tableName: query_queryexecution + indexName: idx_query_queryexecution_query_hash + columns: + column: + name: query_hash + - createIndex: + tableName: query_queryexecution + indexName: idx_query_queryexecution_started_at + columns: + column: + name: started_at + - changeSet: + id: 38 + author: camsaul + changes: + ######################################## Add "points_of_interest" metadata column to various models ######################################## + - addColumn: + tableName: metabase_database + columns: + - column: + name: points_of_interest + type: text + - addColumn: + tableName: metabase_table + columns: + - column: + name: points_of_interest + type: text + - addColumn: + tableName: metabase_field + columns: + - column: + name: points_of_interest + type: text + - addColumn: + tableName: report_dashboard + columns: + - column: + name: points_of_interest + type: text + - addColumn: + tableName: metric + columns: + - column: + name: points_of_interest + type: text + - addColumn: + tableName: segment + columns: + - column: + name: points_of_interest + type: text + ######################################## Add "caveats" metadata column to various models ######################################## + - addColumn: + tableName: metabase_database + columns: + - column: + name: caveats + type: text + - addColumn: + tableName: metabase_table + columns: + - column: + name: caveats + type: text + - addColumn: + tableName: metabase_field + columns: + - column: + name: caveats + type: text + - addColumn: + tableName: report_dashboard + columns: + - column: + name: caveats + type: text + - addColumn: + tableName: metric + columns: + - column: + name: caveats + type: text + - addColumn: + tableName: segment + columns: + - column: + name: caveats + type: text + ######################################## Add "how_is_this_calculated" to metric ######################################## + - addColumn: + tableName: metric + columns: + - column: + name: how_is_this_calculated + type: text + ######################################## Add "most important dashboard" (0 or 1 dashboards) ######################################## + - addColumn: + tableName: report_dashboard + columns: + - column: + name: show_in_getting_started + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - createIndex: + tableName: report_dashboard + indexName: idx_report_dashboard_show_in_getting_started + columns: + column: + name: show_in_getting_started + ######################################## Add "most important metrics" (0+ metrics) ######################################## + - addColumn: + tableName: metric + columns: + - column: + name: show_in_getting_started + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - createIndex: + tableName: metric + indexName: idx_metric_show_in_getting_started + columns: + column: + name: show_in_getting_started + ######################################## Add "most important tables (0+ tables) ######################################## + - addColumn: + tableName: metabase_table + columns: + - column: + name: show_in_getting_started + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - createIndex: + tableName: metabase_table + indexName: idx_metabase_table_show_in_getting_started + columns: + column: + name: show_in_getting_started + ######################################## Add "most important segments" (0+ segments) ######################################## + - addColumn: + tableName: segment + columns: + - column: + name: show_in_getting_started + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - createIndex: + tableName: segment + indexName: idx_segment_show_in_getting_started + columns: + column: + name: show_in_getting_started + ######################################## Add "metric_important_field" table ######################################## + - createTable: + tableName: metric_important_field + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: metric_id + type: int + constraints: + nullable: false + references: metric(id) + foreignKeyName: fk_metric_important_field_metric_id + - column: + name: field_id + type: int + constraints: + nullable: false + references: metabase_field(id) + foreignKeyName: fk_metric_important_field_metabase_field_id + - addUniqueConstraint: + tableName: metric_important_field + columnNames: metric_id, field_id + constraintName: unique_metric_important_field_metric_id_field_id + - createIndex: + tableName: metric_important_field + indexName: idx_metric_important_field_metric_id + columns: + column: + name: metric_id + - createIndex: + tableName: metric_important_field + indexName: idx_metric_important_field_field_id + columns: + column: + name: field_id + - changeSet: + id: 39 + author: camsaul + changes: + - addColumn: + tableName: core_user + columns: + - column: + name: google_auth + type: boolean + defaultValueBoolean: false + constraints: + nullable: false + - changeSet: + id: 40 + author: camsaul + changes: + ############################################################ add PermissionsGroup table ############################################################ + - createTable: + tableName: permissions_group + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + # TODO - it would be nice to make this a case-insensitive unique constraint / index? + - column: + name: name + type: varchar(255) + constraints: + nullable: false + unique: true + uniqueConstraintName: unique_permissions_group_name + - createIndex: + tableName: permissions_group + indexName: idx_permissions_group_name + columns: + column: + name: name + ############################################################ add PermissionsGroupMembership table ############################################################ + - createTable: + tableName: permissions_group_membership + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: user_id + type: int + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_permissions_group_membership_user_id + - column: + name: group_id + type: int + constraints: + nullable: false + references: permissions_group(id) + foreignKeyName: fk_permissions_group_group_id + - addUniqueConstraint: + tableName: permissions_group_membership + columnNames: user_id, group_id + constraintName: unique_permissions_group_membership_user_id_group_id + # for things like all users in a given group + - createIndex: + tableName: permissions_group_membership + indexName: idx_permissions_group_membership_group_id + columns: + column: + name: group_id + # for things like all groups a user belongs to + - createIndex: + tableName: permissions_group_membership + indexName: idx_permissions_group_membership_user_id + columns: + column: + name: user_id + # for things like is given user a member of a given group (TODO - not sure we need this) + - createIndex: + tableName: permissions_group_membership + indexName: idx_permissions_group_membership_group_id_user_id + columns: + column: + name: group_id + column: + name: user_id + ############################################################ add Permissions table ############################################################ + - createTable: + tableName: permissions + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: object + type: varchar(254) + constraints: + nullable: false + - column: + name: group_id + type: int + constraints: + nullable: false + references: permissions_group(id) + foreignKeyName: fk_permissions_group_id + - createIndex: + tableName: permissions + indexName: idx_permissions_group_id + columns: + column: + name: group_id + - createIndex: + tableName: permissions + indexName: idx_permissions_object + columns: + column: + name: object + - createIndex: + tableName: permissions + indexName: idx_permissions_group_id_object + columns: + column: + name: group_id + column: + name: object + - addUniqueConstraint: + tableName: permissions + columnNames: group_id, object + ############################################################ Tweaks to metabase_table ############################################################ + # Modify the length of metabase_table.schema from 256 -> 254 + # It turns out MySQL InnoDB indecies have to be 767 bytes or less (at least for older versions of MySQL) + # and 'utf8' text columns can use up to 3 bytes per character in MySQL -- see http://stackoverflow.com/a/22515986/1198455 + # So 256 * 3 = 768 bytes (too large to index / add unique constraints) + # Drop this to 254; 254 * 3 = 762, which should give us room to index it along with a 4-byte integer as well if need be + # Hoping this doesn't break anyone's existing databases. Hopefully there aren't any schemas that are 255 or 256 bytes long out there; any longer + # and it would have already broke; any shorter and there's not problem. + # Anyway, better to break it now than to leave it as-is and have and break permissions where the columns have to be 254 characters wide + - modifyDataType: + tableName: metabase_table + columnName: schema + newDataType: varchar(254) + # Add index: this is for doing things like getting all the tables that belong to a given schema + - createIndex: + tableName: metabase_table + indexName: idx_metabase_table_db_id_schema + columns: + column: + name: db_id + column: + name: schema + - changeSet: + id: 41 + author: camsaul + changes: + - dropColumn: + tableName: metabase_field + columnName: field_type + - addDefaultValue: + tableName: metabase_field + columnName: active + defaultValueBoolean: true + - addDefaultValue: + tableName: metabase_field + columnName: preview_display + defaultValueBoolean: true + - addDefaultValue: + tableName: metabase_field + columnName: position + defaultValueNumeric: 0 + - addDefaultValue: + tableName: metabase_field + columnName: visibility_type + defaultValue: "normal" + - changeSet: + id: 42 + author: camsaul + changes: + - dropForeignKeyConstraint: + baseTableName: query_queryexecution + constraintName: fk_queryexecution_ref_query_id + - dropColumn: + tableName: query_queryexecution + columnName: query_id + - dropColumn: + tableName: core_user + columnName: is_staff + - dropColumn: + tableName: metabase_database + columnName: organization_id + - dropColumn: + tableName: report_card + columnName: organization_id + - dropColumn: + tableName: report_dashboard + columnName: organization_id + - dropTable: + tableName: annotation_annotation + - dropTable: + tableName: core_permissionsviolation + - dropTable: + tableName: core_userorgperm + - dropTable: + tableName: core_organization + - dropTable: + tableName: metabase_foreignkey + - dropTable: + tableName: metabase_tablesegment + - dropTable: + tableName: query_query + - dropTable: + tableName: report_dashboardsubscription + - dropTable: + tableName: report_emailreport_recipients + - dropTable: + tableName: report_emailreportexecutions + - dropTable: + tableName: report_emailreport + - changeSet: + id: 43 + author: camsaul + validCheckSum: 7:b20750a949504e93efced32877a4488f + validCheckSum: 7:dbc18c8ca697fc335869f0ed0eb5f4cb + changes: + - createTable: + tableName: permissions_revision + remarks: 'Used to keep track of changes made to permissions.' + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: before + type: text + remarks: 'Serialized JSON of the permissions before the changes.' + constraints: + nullable: false + - column: + name: after + type: text + remarks: 'Serialized JSON of the permissions after the changes.' + constraints: + nullable: false + - column: + name: user_id + type: int + remarks: 'The ID of the admin who made this set of changes.' + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_permissions_revision_user_id + - column: + name: created_at + type: datetime + remarks: 'The timestamp of when these changes were made.' + constraints: + nullable: false + - column: + name: remark + type: text + remarks: 'Optional remarks explaining why these changes were made.' + - changeSet: + id: 44 + author: camsaul + changes: + - dropColumn: + tableName: report_card + columnName: public_perms + - dropColumn: + tableName: report_dashboard + columnName: public_perms + - dropColumn: + tableName: pulse + columnName: public_perms + - changeSet: + id: 45 + author: tlrobinson + changes: + - addColumn: + tableName: report_dashboardcard + columns: + - column: + name: visualization_settings + type: text + - addNotNullConstraint: + tableName: report_dashboardcard + columnName: visualization_settings + columnDataType: text + defaultNullValue: '{}' + - changeSet: + id: 46 + author: camsaul + changes: + - addNotNullConstraint: + tableName: report_dashboardcard + columnName: row + columnDataType: integer + defaultNullValue: 0 + - addNotNullConstraint: + tableName: report_dashboardcard + columnName: col + columnDataType: integer + defaultNullValue: 0 + - addDefaultValue: + tableName: report_dashboardcard + columnName: row + defaultValueNumeric: 0 + - addDefaultValue: + tableName: report_dashboardcard + columnName: col + defaultValueNumeric: 0 + - changeSet: + id: 47 + author: camsaul + changes: + ######################################## collection table ######################################## + - createTable: + tableName: collection + remarks: 'Collections are an optional way to organize Cards and handle permissions for them.' + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: name + type: text + remarks: 'The unique, user-facing name of this Collection.' + constraints: + nullable: false + - column: + name: slug + type: varchar(254) + remarks: 'URL-friendly, sluggified, indexed version of name.' + constraints: + nullable: false + unique: true + - column: + name: description + type: text + remarks: 'Optional description for this Collection.' + - column: + name: color + type: char(7) + remarks: 'Seven-character hex color for this Collection, including the preceding hash sign.' + constraints: + nullable: false + - column: + name: archived + type: boolean + remarks: 'Whether this Collection has been archived and should be hidden from users.' + defaultValueBoolean: false + constraints: + nullable: false + - createIndex: + tableName: collection + indexName: idx_collection_slug + columns: + column: + name: slug + ######################################## add collection_id to report_card ######################################## + - addColumn: + tableName: report_card + columns: + - column: + name: collection_id + type: int + remarks: 'Optional ID of Collection this Card belongs to.' + constraints: + references: collection(id) + foreignKeyName: fk_card_collection_id + - createIndex: + tableName: report_card + indexName: idx_card_collection_id + columns: + column: + name: collection_id + - changeSet: + id: 48 + author: camsaul + changes: + - createTable: + tableName: collection_revision + remarks: 'Used to keep track of changes made to collections.' + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: before + type: text + remarks: 'Serialized JSON of the collections graph before the changes.' + constraints: + nullable: false + - column: + name: after + type: text + remarks: 'Serialized JSON of the collections graph after the changes.' + constraints: + nullable: false + - column: + name: user_id + type: int + remarks: 'The ID of the admin who made this set of changes.' + constraints: + nullable: false + references: core_user(id) + foreignKeyName: fk_collection_revision_user_id + - column: + name: created_at + type: datetime + remarks: 'The timestamp of when these changes were made.' + constraints: + nullable: false + - column: + name: remark + type: text + remarks: 'Optional remarks explaining why these changes were made.' + - changeSet: + id: 49 + author: camsaul + changes: + ######################################## Card public_uuid & indecies ######################################## + - addColumn: + tableName: report_card + columns: + - column: + name: public_uuid + type: char(36) + remarks: 'Unique UUID used to in publically-accessible links to this Card.' + constraints: + unique: true + - column: + name: made_public_by_id + type: int + remarks: 'The ID of the User who first publically shared this Card.' + constraints: + references: core_user(id) + foreignKeyName: fk_card_made_public_by_id + - createIndex: + tableName: report_card + indexName: idx_card_public_uuid + columns: + column: + name: public_uuid + ######################################## Dashboard public_uuid & indecies ######################################## + - addColumn: + tableName: report_dashboard + columns: + - column: + name: public_uuid + type: char(36) + remarks: 'Unique UUID used to in publically-accessible links to this Dashboard.' + constraints: + unique: true + - column: + name: made_public_by_id + type: int + remarks: 'The ID of the User who first publically shared this Dashboard.' + constraints: + references: core_user(id) + foreignKeyName: fk_dashboard_made_public_by_id + - createIndex: + tableName: report_dashboard + indexName: idx_dashboard_public_uuid + columns: + column: + name: public_uuid + ######################################## make query_queryexecution.executor_id nullable ######################################## + - dropNotNullConstraint: + tableName: query_queryexecution + columnName: executor_id + columnDataType: int + - changeSet: + id: 50 + author: camsaul + changes: + ######################################## new Card columns ######################################## + - addColumn: + tableName: report_card + columns: + - column: + name: enable_embedding + type: boolean + remarks: 'Is this Card allowed to be embedded in different websites (using a signed JWT)?' + defaultValueBoolean: false + constraints: + nullable: false + - column: + name: embedding_params + type: text + remarks: 'Serialized JSON containing information about required parameters that must be supplied when embedding this Card.' + ######################################## new Card columns ######################################## + - addColumn: + tableName: report_dashboard + columns: + - column: + name: enable_embedding + type: boolean + remarks: 'Is this Dashboard allowed to be embedded in different websites (using a signed JWT)?' + defaultValueBoolean: false + constraints: + nullable: false + - column: + name: embedding_params + type: text + remarks: 'Serialized JSON containing information about required parameters that must be supplied when embedding this Dashboard.' + - changeSet: + id: 51 + author: camsaul + changes: + - createTable: + tableName: query_execution + remarks: 'A log of executed queries, used for calculating historic execution times, auditing, and other purposes.' + columns: + - column: + name: id + type: int + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: hash + type: binary(32) + remarks: 'The hash of the query dictionary. This is a 256-bit SHA3 hash of the query.' + constraints: + nullable: false + - column: + name: started_at + type: datetime + remarks: 'Timestamp of when this query started running.' + constraints: + nullable: false + - column: + name: running_time + type: integer + remarks: 'The time, in milliseconds, this query took to complete.' + constraints: + nullable: false + - column: + name: result_rows + type: integer + remarks: 'Number of rows in the query results.' + constraints: + nullable: false + - column: + name: native + type: boolean + remarks: 'Whether the query was a native query, as opposed to an MBQL one (e.g., created with the GUI).' + constraints: + nullable: false + - column: + name: context + type: varchar(32) + remarks: 'Short string specifying how this query was executed, e.g. in a Dashboard or Pulse.' + - column: + name: error + type: text + remarks: 'Error message returned by failed query, if any.' + # The following columns are foreign keys, but we don't keep FK constraints on them for a few reasons: + # - We don't want to keep indexes on these columns since they wouldn't be generally useful and for size and performance reasons + # - If a related object (e.g. a Dashboard) is deleted, we don't want to delete the related entries in the QueryExecution log. + # We could do something like make the constraint ON DELETE SET NULL, but that would require a full table scan to handle; + # If the QueryExecution log became tens of millions of rows large it would take a very long time to scan and update records + - column: + name: executor_id + type: integer + remarks: 'The ID of the User who triggered this query execution, if any.' + - column: + name: card_id + type: integer + remarks: 'The ID of the Card (Question) associated with this query execution, if any.' + - column: + name: dashboard_id + type: integer + remarks: 'The ID of the Dashboard associated with this query execution, if any.' + - column: + name: pulse_id + type: integer + remarks: 'The ID of the Pulse associated with this query execution, if any.' + # For things like auditing recently executed queries + - createIndex: + tableName: query_execution + indexName: idx_query_execution_started_at + columns: + column: + name: started_at + # For things like seeing the 10 most recent executions of a certain query + - createIndex: + tableName: query_execution + indexName: idx_query_execution_query_hash_started_at + columns: + column: + name: query_hash + column: + name: started_at + - property: + name: blob.type + value: blob + dbms: mysql,h2 + - property: + name: blob.type + value: bytea + dbms: postgresql + - changeSet: + id: 52 + author: camsaul + changes: + - createTable: + tableName: query_cache + remarks: 'Cached results of queries are stored here when using the DB-based query cache.' + columns: + - column: + name: query_hash + type: binary(32) + remarks: 'The hash of the query dictionary. (This is a 256-bit SHA3 hash of the query dict).' + constraints: + primaryKey: true + nullable: false + - column: + name: updated_at + type: datetime + remarks: 'The timestamp of when these query results were last refreshed.' + constraints: + nullable: false + - column: + name: results + type: ${blob.type} + remarks: 'Cached, compressed results of running the query with the given hash.' + constraints: + nullable: false + - createIndex: + tableName: query_cache + indexName: idx_query_cache_updated_at + columns: + column: + name: updated_at + - addColumn: + tableName: report_card + columns: + - column: + name: cache_ttl + type: int + remarks: 'The maximum time, in seconds, to return cached results for this Card rather than running a new query.' + - changeSet: + id: 53 + author: camsaul + changes: + - createTable: + tableName: query + remarks: 'Information (such as average execution time) for different queries that have been previously ran.' + columns: + - column: + name: query_hash + type: binary(32) + remarks: 'The hash of the query dictionary. (This is a 256-bit SHA3 hash of the query dict.)' + constraints: + primaryKey: true + nullable: false + - column: + name: average_execution_time + type: int + remarks: 'Average execution time for the query, round to nearest number of milliseconds. This is updated as a rolling average.' + constraints: + nullable: false + - changeSet: + id: 54 + author: tlrobinson + changes: + - addColumn: + tableName: pulse + remarks: 'Skip a scheduled Pulse if none of its questions have any results' + columns: + - column: + name: skip_if_empty + type: boolean + defaultValueBoolean: false + constraints: + nullable: false diff --git a/resources/migrations/001_initial_schema.json b/resources/migrations/001_initial_schema.json deleted file mode 100644 index 116cc883a0bd9631d75f14a07347c7a525793cd1..0000000000000000000000000000000000000000 --- a/resources/migrations/001_initial_schema.json +++ /dev/null @@ -1,2194 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "1", - "author": "agilliland", - "changes": [ - { - "createTable": { - "tableName": "core_organization", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "slug", - "type": "varchar(254)", - "constraints": { - "unique": true, - "nullable": false - } - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "description", - "type": "text" - } - }, - { - "column": { - "name": "logo_url", - "type": "varchar(254)" - } - }, - { - "column": { - "name": "inherits", - "type": "boolean", - "constraints": {"nullable": false} - } - } - ] - } - }, - - { - "createTable": { - "tableName": "core_user", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "email", - "type": "varchar(254)", - "constraints": { - "unique": true, - "nullable": false - } - } - }, - { - "column": { - "name": "first_name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "last_name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "password", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "password_salt", - "type": "varchar(254)", - "defaultValue": "default", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "date_joined", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "last_login", - "type": "DATETIME", - "constraints": {"nullable": true} - } - }, - { - "column": { - "name": "is_staff", - "type": "boolean", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "is_superuser", - "type": "boolean", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "is_active", - "type": "boolean", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "reset_token", - "type": "varchar(254)" - } - }, - { - "column": { - "name": "reset_triggered", - "type": "BIGINT" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "core_userorgperm", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "admin", - "type": "boolean", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "user_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_userorgperm_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "organization_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_organization(id)", - "foreignKeyName": "fk_userorgperm_ref_organization_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "addUniqueConstraint": { - "tableName": "core_userorgperm", - "constraintName": "idx_unique_user_id_organization_id", - "columnNames": "user_id, organization_id" - } - }, - { - "createIndex": { - "tableName": "core_userorgperm", - "indexName": "idx_userorgperm_user_id", - "columns": [ - { - "column": { - "name": "user_id", - "type": "int" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "core_userorgperm", - "indexName": "idx_userorgperm_organization_id", - "columns": [ - { - "column": { - "name": "organization_id", - "type": "int" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "core_permissionsviolation", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "url", - "type": "varchar(254)", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "timestamp", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "user_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_permissionviolation_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "core_permissionsviolation", - "indexName": "idx_permissionsviolation_user_id", - "columns": [ - { - "column": { - "name": "user_id", - "type": "int" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "metabase_database", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "description", - "type": "text" - } - }, - { - "column": { - "name": "organization_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_organization(id)", - "foreignKeyName": "fk_database_ref_organization_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "details", - "type": "text" - } - }, - { - "column": { - "name": "engine", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - } - ] - } - }, - { - "createIndex": { - "tableName": "metabase_database", - "indexName": "idx_database_organization_id", - "columns": [ - { - "column": { - "name": "organization_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "metabase_table", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "rows", - "type": "int" - } - }, - { - "column": { - "name": "description", - "type": "text" - } - }, - { - "column": { - "name": "entity_name", - "type": "varchar(254)" - } - }, - { - "column": { - "name": "entity_type", - "type": "varchar(254)" - } - }, - { - "column": { - "name": "active", - "type": "boolean", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "db_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "metabase_database(id)", - "foreignKeyName": "fk_table_ref_database_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "metabase_table", - "indexName": "idx_table_db_id", - "columns": [ - { - "column": { - "name": "db_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "metabase_field", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "base_type", - "type": "varchar(255)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "special_type", - "type": "varchar(255)" - } - }, - { - "column": { - "name": "active", - "type": "boolean", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "description", - "type": "text" - } - }, - { - "column": { - "name": "preview_display", - "type": "boolean", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "position", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "table_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "metabase_table(id)", - "foreignKeyName": "fk_field_ref_table_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "field_type", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - } - ] - } - }, - { - "createIndex": { - "tableName": "metabase_field", - "indexName": "idx_field_table_id", - "columns": [ - { - "column": { - "name": "table_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "metabase_foreignkey", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "relationship", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "destination_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "metabase_field(id)", - "foreignKeyName": "fk_foreignkey_dest_ref_field_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "origin_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "metabase_field(id)", - "foreignKeyName": "fk_foreignkey_origin_ref_field_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "metabase_foreignkey", - "indexName": "idx_foreignkey_destination_id", - "columns": [ - { - "column": { - "name": "destination_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "metabase_foreignkey", - "indexName": "idx_foreignkey_origin_id", - "columns": [ - { - "column": { - "name": "origin_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "metabase_fieldvalues", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "values", - "type": "text" - } - }, - { - "column": { - "name": "human_readable_values", - "type": "text" - } - }, - { - "column": { - "name": "field_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "metabase_field(id)", - "foreignKeyName": "fk_fieldvalues_ref_field_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "metabase_fieldvalues", - "indexName": "idx_fieldvalues_field_id", - "columns": [ - { - "column": { - "name": "field_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "metabase_tablesegment", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "table_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "metabase_table(id)", - "foreignKeyName": "fk_tablesegment_ref_table_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "filter_clause", - "type": "text", - "constraints": { - "nullable": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "metabase_tablesegment", - "indexName": "idx_tablesegment_table_id", - "columns": [ - { - "column": { - "name": "table_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "query_query", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "type", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "details", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "version", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "public_perms", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "creator_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_query_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "database_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "metabase_database(id)", - "foreignKeyName": "fk_query_ref_database_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "query_query", - "indexName": "idx_query_creator_id", - "columns": [ - { - "column": { - "name": "creator_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "query_query", - "indexName": "idx_query_database_id", - "columns": [ - { - "column": { - "name": "database_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "query_queryexecution", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "uuid", - "type": "varchar(254)", - "constraints": { - "nullable": false, - "unique": true - } - } - }, - { - "column": { - "name": "version", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "json_query", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "raw_query", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "status", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "started_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "finished_at", - "type": "DATETIME" - } - }, - { - "column": { - "name": "running_time", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "error", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "result_file", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "result_rows", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "result_data", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "query_id", - "type": "int", - "constraints": { - "nullable": true, - "references": "query_query(id)", - "foreignKeyName": "fk_queryexecution_ref_query_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "additional_info", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "executor_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_queryexecution_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "query_queryexecution", - "indexName": "idx_queryexecution_query_id", - "columns": [ - { - "column": { - "name": "query_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "query_queryexecution", - "indexName": "idx_queryexecution_executor_id", - "columns": [ - { - "column": { - "name": "executor_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_card", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "description", - "type": "text" - } - }, - { - "column": { - "name": "display", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "public_perms", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "dataset_query", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "visualization_settings", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "creator_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_card_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "organization_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_organization(id)", - "foreignKeyName": "fk_card_ref_organization_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_card", - "indexName": "idx_card_creator_id", - "columns": [ - { - "column": { - "name": "creator_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_card", - "indexName": "idx_card_organization_id", - "columns": [ - { - "column": { - "name": "organization_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_cardfavorite", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "card_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "report_card(id)", - "foreignKeyName": "fk_cardfavorite_ref_card_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "owner_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_cardfavorite_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "addUniqueConstraint": { - "tableName": "report_cardfavorite", - "constraintName": "idx_unique_cardfavorite_card_id_owner_id", - "columnNames": "card_id, owner_id" - } - }, - { - "createIndex": { - "tableName": "report_cardfavorite", - "indexName": "idx_cardfavorite_card_id", - "columns": [ - { - "column": { - "name": "card_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_cardfavorite", - "indexName": "idx_cardfavorite_owner_id", - "columns": [ - { - "column": { - "name": "owner_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_dashboard", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "description", - "type": "text" - } - }, - { - "column": { - "name": "public_perms", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "creator_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_dashboard_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "organization_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_organization(id)", - "foreignKeyName": "fk_dashboard_ref_organization_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_dashboard", - "indexName": "idx_dashboard_creator_id", - "columns": [ - { - "column": { - "name": "creator_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_dashboard", - "indexName": "idx_dashboard_organization_id", - "columns": [ - { - "column": { - "name": "organization_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_dashboardcard", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "sizeX", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "sizeY", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "row", - "type": "int" - } - }, - { - "column": { - "name": "col", - "type": "int" - } - }, - { - "column": { - "name": "card_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "report_card(id)", - "foreignKeyName": "fk_dashboardcard_ref_card_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "dashboard_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "report_dashboard(id)", - "foreignKeyName": "fk_dashboardcard_ref_dashboard_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_dashboardcard", - "indexName": "idx_dashboardcard_card_id", - "columns": [ - { - "column": { - "name": "card_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_dashboardcard", - "indexName": "idx_dashboardcard_dashboard_id", - "columns": [ - { - "column": { - "name": "dashboard_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_dashboardsubscription", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "dashboard_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "report_dashboard(id)", - "foreignKeyName": "fk_dashboardsubscription_ref_dashboard_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "user_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_dashboardsubscription_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "addUniqueConstraint": { - "tableName": "report_dashboardsubscription", - "constraintName": "idx_uniq_dashsubscrip_dashboard_id_user_id", - "columnNames": "dashboard_id, user_id" - } - }, - { - "createIndex": { - "tableName": "report_dashboardsubscription", - "indexName": "idx_dashboardsubscription_dashboard_id", - "columns": [ - { - "column": { - "name": "dashboard_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_dashboardsubscription", - "indexName": "idx_dashboardsubscription_user_id", - "columns": [ - { - "column": { - "name": "user_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_emailreport", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "name", - "type": "varchar(254)", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "description", - "type": "text" - } - }, - { - "column": { - "name": "public_perms", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "mode", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "version", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "dataset_query", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "email_addresses", - "type": "text" - } - }, - { - "column": { - "name": "creator_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_emailreport_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "organization_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_organization(id)", - "foreignKeyName": "fk_emailreport_ref_organization_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "schedule", - "type": "text", - "constraints": {"nullable": false} - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_emailreport", - "indexName": "idx_emailreport_creator_id", - "columns": [ - { - "column": { - "name": "creator_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_emailreport", - "indexName": "idx_emailreport_organization_id", - "columns": [ - { - "column": { - "name": "organization_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_emailreport_recipients", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "emailreport_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "report_emailreport(id)", - "foreignKeyName": "fk_emailreport_recipients_ref_emailreport_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "user_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_emailreport_recipients_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "addUniqueConstraint": { - "tableName": "report_emailreport_recipients", - "constraintName": "idx_uniq_emailreportrecip_emailreport_id_user_id", - "columnNames": "emailreport_id, user_id" - } - }, - { - "createIndex": { - "tableName": "report_emailreport_recipients", - "indexName": "idx_emailreport_recipients_emailreport_id", - "columns": [ - { - "column": { - "name": "emailreport_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_emailreport_recipients", - "indexName": "idx_emailreport_recipients_user_id", - "columns": [ - { - "column": { - "name": "user_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "report_emailreportexecutions", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "details", - "type": "text", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "status", - "type": "varchar(254)", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - }, - { - "column": { - "name": "started_at", - "type": "DATETIME" - } - }, - { - "column": { - "name": "finished_at", - "type": "DATETIME" - } - }, - { - "column": { - "name": "error", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "sent_email", - "type": "text", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "organization_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_organization(id)", - "foreignKeyName": "fk_emailreportexecutions_ref_organization_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "report_id", - "type": "int", - "constraints": { - "nullable": true, - "references": "report_emailreport(id)", - "foreignKeyName": "fk_emailreportexecutions_ref_report_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_emailreportexecutions", - "indexName": "idx_emailreportexecutions_organization_id", - "columns": [ - { - "column": { - "name": "organization_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "report_emailreportexecutions", - "indexName": "idx_emailreportexecutions_report_id", - "columns": [ - { - "column": { - "name": "report_id" - } - } - ] - } - }, - - { - "createTable": { - "tableName": "annotation_annotation", - "columns": [ - { - "column": { - "name": "id", - "type": "int", - "autoIncrement": true, - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "updated_at", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "start", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "end", - "type": "DATETIME", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "title", - "type": "TEXT" - } - }, - { - "column": { - "name": "body", - "type": "TEXT", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "annotation_type", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "edit_count", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "object_type_id", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "object_id", - "type": "int", - "constraints": {"nullable": false} - } - }, - { - "column": { - "name": "author_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_annotation_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "organization_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_organization(id)", - "foreignKeyName": "fk_annotation_ref_organization_id", - "deferrable": false, - "initiallyDeferred": false - } - } - } - ] - } - }, - { - "createIndex": { - "tableName": "annotation_annotation", - "indexName": "idx_annotation_author_id", - "columns": [ - { - "column": { - "name": "author_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "annotation_annotation", - "indexName": "idx_annotation_organization_id", - "columns": [ - { - "column": { - "name": "organization_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "annotation_annotation", - "indexName": "idx_annotation_object_type_id", - "columns": [ - { - "column": { - "name": "object_type_id" - } - } - ] - } - }, - { - "createIndex": { - "tableName": "annotation_annotation", - "indexName": "idx_annotation_object_id", - "columns": [ - { - "column": { - "name": "object_id" - } - } - ] - } - }, - - { - "modifySql": { - "dbms": "postgresql", - "replace": { - "replace": "WITHOUT", - "with": "WITH" - } - } - } - ] - } - } - ] -} diff --git a/resources/migrations/002_add_session_table.json b/resources/migrations/002_add_session_table.json deleted file mode 100644 index 1f1e630be4a6015ebd5606dcf4b075e0f6cd01e6..0000000000000000000000000000000000000000 --- a/resources/migrations/002_add_session_table.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "2", - "author": "agilliland", - "changes": [ - { - "createTable": { - "tableName": "core_session", - "columns": [ - { - "column": { - "name": "id", - "type": "varchar(254)", - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "user_id", - "type": "int", - "constraints": { - "nullable": false, - "references": "core_user(id)", - "foreignKeyName": "fk_session_ref_user_id", - "deferrable": false, - "initiallyDeferred": false - } - } - }, - { - "column": { - "name": "created_at", - "type": "DATETIME", - "constraints": { - "nullable": false - } - } - } - ] - } - }, - - { - "modifySql": { - "dbms": "postgresql", - "replace": { - "replace": "WITHOUT", - "with": "WITH" - } - } - } - ] - } - } - ] -} \ No newline at end of file diff --git a/resources/migrations/004_add_setting_table.json b/resources/migrations/004_add_setting_table.json deleted file mode 100644 index b82ff8fd46ef951b3ce5e1c51b0b1e3750fc6ed7..0000000000000000000000000000000000000000 --- a/resources/migrations/004_add_setting_table.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "4", - "author": "cammsaul", - "changes": [ - { - "createTable": { - "tableName": "setting", - "columns": [ - { - "column": { - "name": "key", - "type": "varchar(254)", - "constraints": { - "primaryKey": true, - "nullable": false - } - } - }, - { - "column": { - "name": "value", - "type": "varchar(254)", - "constraints": { - "nullable": false - } - } - } - ] - } - } - ] - } - } - ] -} diff --git a/resources/migrations/005_add_org_report_tz_column.json b/resources/migrations/005_add_org_report_tz_column.json deleted file mode 100644 index 480fbb0758a4a6c57b328239a9d3f0d3e80b5dad..0000000000000000000000000000000000000000 --- a/resources/migrations/005_add_org_report_tz_column.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "5", - "author": "agilliland", - "changes": [ - { - "addColumn": { - "tableName": "core_organization", - "columns": [ - { - "column": { - "name": "report_timezone", - "type": "varchar(254)" - } - } - ] - } - } - ] - } - } - ] -} diff --git a/resources/migrations/006_disconnect_orgs.json b/resources/migrations/006_disconnect_orgs.json deleted file mode 100644 index fb792b15d204d8ecf61683c5192db479b037715d..0000000000000000000000000000000000000000 --- a/resources/migrations/006_disconnect_orgs.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "6", - "author": "agilliland", - "changes": [ - { - "dropNotNullConstraint": { - "tableName": "metabase_database", - "columnDataType": "int", - "columnName": "organization_id" - } - }, - { - "dropForeignKeyConstraint": { - "baseTableName": "metabase_database", - "constraintName": "fk_database_ref_organization_id" - } - }, - { - "dropNotNullConstraint": { - "tableName": "report_card", - "columnDataType": "int", - "columnName": "organization_id" - } - }, - { - "dropForeignKeyConstraint": { - "baseTableName": "report_card", - "constraintName": "fk_card_ref_organization_id" - } - }, - { - "dropNotNullConstraint": { - "tableName": "report_dashboard", - "columnDataType": "int", - "columnName": "organization_id" - } - }, - { - "dropForeignKeyConstraint": { - "baseTableName": "report_dashboard", - "constraintName": "fk_dashboard_ref_organization_id" - } - }, - { - "dropNotNullConstraint": { - "tableName": "report_emailreport", - "columnDataType": "int", - "columnName": "organization_id" - } - }, - { - "dropForeignKeyConstraint": { - "baseTableName": "report_emailreport", - "constraintName": "fk_emailreport_ref_organization_id" - } - }, - { - "dropNotNullConstraint": { - "tableName": "report_emailreportexecutions", - "columnDataType": "int", - "columnName": "organization_id" - } - }, - { - "dropForeignKeyConstraint": { - "baseTableName": "report_emailreportexecutions", - "constraintName": "fk_emailreportexecutions_ref_organization_id" - } - }, - { - "dropNotNullConstraint": { - "tableName": "annotation_annotation", - "columnDataType": "int", - "columnName": "organization_id" - } - }, - { - "dropForeignKeyConstraint": { - "baseTableName": "annotation_annotation", - "constraintName": "fk_annotation_ref_organization_id" - } - } - ] - } - } - ] -} diff --git a/resources/migrations/007_add_field_parent_id.json b/resources/migrations/007_add_field_parent_id.json deleted file mode 100644 index d2fd5df82bb57753795ffcf4da312627c444771e..0000000000000000000000000000000000000000 --- a/resources/migrations/007_add_field_parent_id.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "7", - "author": "cammsaul", - "changes": [ - { - "addColumn": { - "tableName": "metabase_field", - "columns": [ - { - "column": { - "name": "parent_id", - "type": "int", - "constraints": { - "nullable": true, - "references": "metabase_field(id)", - "foreignKeyName": "fk_field_parent_ref_field_id" - } - } - } - ] - } - } - ] - } - } - ] -} diff --git a/resources/migrations/008_add_display_name_columns.json b/resources/migrations/008_add_display_name_columns.json deleted file mode 100644 index 8eb9794ba7a40ad1519656a41681a17bb4125cba..0000000000000000000000000000000000000000 --- a/resources/migrations/008_add_display_name_columns.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "8", - "author": "tlrobinson", - "changes": [ - { - "addColumn": { - "tableName": "metabase_table", - "columns": [ - { - "column": { - "name": "display_name", - "type": "varchar(254)" - } - } - ] - } - }, - { - "addColumn": { - "tableName": "metabase_field", - "columns": [ - { - "column": { - "name": "display_name", - "type": "varchar(254)" - } - } - ] - } - } - ] - } - } - ] -} diff --git a/resources/migrations/009_add_table_visibility_type_column.json b/resources/migrations/009_add_table_visibility_type_column.json deleted file mode 100644 index 74aa0a69cb50e629a11d658911711d4eb2aa9f8b..0000000000000000000000000000000000000000 --- a/resources/migrations/009_add_table_visibility_type_column.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "databaseChangeLog": [ - { - "changeSet": { - "id": "9", - "author": "tlrobinson", - "changes": [ - { - "addColumn": { - "tableName": "metabase_table", - "columns": [ - { - "column": { - "name": "visibility_type", - "type": "varchar(254)" - } - } - ] - } - } - ] - } - } - ] -} diff --git a/resources/migrations/010_add_revision_table.yaml b/resources/migrations/010_add_revision_table.yaml deleted file mode 100644 index 95b0a4bfd7f064e2e24faaa8c87cdc6ed70feada..0000000000000000000000000000000000000000 --- a/resources/migrations/010_add_revision_table.yaml +++ /dev/null @@ -1,68 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 10 - author: cammsaul - changes: - - createTable: - tableName: revision - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: model - type: varchar(16) - constraints: - nullable: false - - column: - name: model_id - type: int - constraints: - nullable: false - - column: - name: user_id - type: int - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_revision_ref_user_id - deferrable: false - initiallyDeferred: false - - column: - name: timestamp - type: DATETIME - constraints: - nullable: false - - column: - name: object - type: varchar - constraints: - nullable: false - - column: - name: is_reversion - type: boolean - defaultValueBoolean: false - constraints: - nullable: false - - createIndex: - tableName: revision - indexName: idx_revision_model_model_id - columns: - column: - name: model - column: - name: model_id - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH - - modifySql: - dbms: mysql - replace: - replace: object VARCHAR - with: object TEXT diff --git a/resources/migrations/011_cleanup_dashboard_perms.yaml b/resources/migrations/011_cleanup_dashboard_perms.yaml deleted file mode 100644 index 4ae87decd018e8c2c4aed9665362b3e3b23d9000..0000000000000000000000000000000000000000 --- a/resources/migrations/011_cleanup_dashboard_perms.yaml +++ /dev/null @@ -1,7 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 11 - author: agilliland - changes: - - sql: - sql: update report_dashboard set public_perms = 2 where public_perms = 1 diff --git a/resources/migrations/012_add_card_query_fields.yaml b/resources/migrations/012_add_card_query_fields.yaml deleted file mode 100644 index 437cc5c73c08b5f8c4ab686b0ac7caccd3743589..0000000000000000000000000000000000000000 --- a/resources/migrations/012_add_card_query_fields.yaml +++ /dev/null @@ -1,31 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 12 - author: agilliland - changes: - - addColumn: - tableName: report_card - columns: - - column: - name: database_id - type: int - constraints: - nullable: true - references: metabase_database(id) - foreignKeyName: fk_report_card_ref_database_id - deferrable: false - initiallyDeferred: false - - column: - name: table_id - type: int - constraints: - nullable: true - references: metabase_table(id) - foreignKeyName: fk_report_card_ref_table_id - deferrable: false - initiallyDeferred: false - - column: - name: query_type - type: varchar(16) - constraints: - nullable: true diff --git a/resources/migrations/013_add_activity_table.yaml b/resources/migrations/013_add_activity_table.yaml deleted file mode 100644 index 8ba808a23af036a133fbb2c866f7acf5796182ae..0000000000000000000000000000000000000000 --- a/resources/migrations/013_add_activity_table.yaml +++ /dev/null @@ -1,92 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 13 - author: agilliland - changes: - - createTable: - tableName: activity - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: topic - type: varchar(32) - constraints: - nullable: false - - column: - name: timestamp - type: DATETIME - constraints: - nullable: false - - column: - name: user_id - type: int - constraints: - nullable: true - references: core_user(id) - foreignKeyName: fk_activity_ref_user_id - deferrable: false - initiallyDeferred: false - - column: - name: model - type: varchar(16) - constraints: - nullable: true - - column: - name: model_id - type: int - constraints: - nullable: true - - column: - name: database_id - type: int - constraints: - nullable: true - - column: - name: table_id - type: int - constraints: - nullable: true - - column: - name: custom_id - type: varchar(48) - constraints: - nullable: true - - column: - name: details - type: varchar - constraints: - nullable: false - - createIndex: - tableName: activity - indexName: idx_activity_timestamp - columns: - column: - name: timestamp - - createIndex: - tableName: activity - indexName: idx_activity_user_id - columns: - column: - name: user_id - - createIndex: - tableName: activity - indexName: idx_activity_custom_id - columns: - column: - name: custom_id - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH - - modifySql: - dbms: mysql - replace: - replace: details VARCHAR - with: details TEXT diff --git a/resources/migrations/014_add_view_log_table.yaml b/resources/migrations/014_add_view_log_table.yaml deleted file mode 100644 index 717aad9ce336694a5a1d78afa415639c4651d1de..0000000000000000000000000000000000000000 --- a/resources/migrations/014_add_view_log_table.yaml +++ /dev/null @@ -1,56 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 14 - author: agilliland - changes: - - createTable: - tableName: view_log - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: user_id - type: int - constraints: - nullable: true - references: core_user(id) - foreignKeyName: fk_view_log_ref_user_id - deferrable: false - initiallyDeferred: false - - column: - name: model - type: varchar(16) - constraints: - nullable: false - - column: - name: model_id - type: int - constraints: - nullable: false - - column: - name: timestamp - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: view_log - indexName: idx_view_log_user_id - columns: - column: - name: user_id - - createIndex: - tableName: view_log - indexName: idx_view_log_timestamp - columns: - column: - name: model_id - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/015_add_revision_is_creation_field.yaml b/resources/migrations/015_add_revision_is_creation_field.yaml deleted file mode 100644 index c5ec9bf635814e7c16d3a29c1b58258bc08e479c..0000000000000000000000000000000000000000 --- a/resources/migrations/015_add_revision_is_creation_field.yaml +++ /dev/null @@ -1,14 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 15 - author: agilliland - changes: - - addColumn: - tableName: revision - columns: - - column: - name: is_creation - type: boolean - defaultValueBoolean: false - constraints: - nullable: false diff --git a/resources/migrations/016_user_last_login_allow_null.yaml b/resources/migrations/016_user_last_login_allow_null.yaml deleted file mode 100644 index 596844402b956f0e5588f5a4ca0f7c7f3403fff4..0000000000000000000000000000000000000000 --- a/resources/migrations/016_user_last_login_allow_null.yaml +++ /dev/null @@ -1,14 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 16 - author: agilliland - changes: - - dropNotNullConstraint: - tableName: core_user - columnName: last_login - columnDataType: DATETIME - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/017_add_database_is_sample_field.yaml b/resources/migrations/017_add_database_is_sample_field.yaml deleted file mode 100644 index d99263a36d327b6476def89d245f76ff9271d09b..0000000000000000000000000000000000000000 --- a/resources/migrations/017_add_database_is_sample_field.yaml +++ /dev/null @@ -1,16 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 17 - author: agilliland - changes: - - addColumn: - tableName: metabase_database - columns: - - column: - name: is_sample - type: boolean - defaultValueBoolean: false - constraints: - nullable: false - - sql: - sql: update metabase_database set is_sample = true where name = 'Sample Dataset' diff --git a/resources/migrations/018_add_data_migrations_table.yaml b/resources/migrations/018_add_data_migrations_table.yaml deleted file mode 100644 index 34cf546455dbd07022575394b755afbdf16a0ace..0000000000000000000000000000000000000000 --- a/resources/migrations/018_add_data_migrations_table.yaml +++ /dev/null @@ -1,27 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 18 - author: camsaul - validCheckSum: 7:07d501a6e52c14691f7f895d137e565f - validCheckSum: 7:329d897d44ba9893fdafc9ce7e876d73 - changes: - - createTable: - tableName: data_migrations - columns: - - column: - name: id - type: VARCHAR(254) - constraints: - primaryKey: true - nullable: false - - column: - name: timestamp - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: data_migrations - indexName: idx_data_migrations_id - columns: - column: - name: id diff --git a/resources/migrations/019_add_schema_column_to_table.yaml b/resources/migrations/019_add_schema_column_to_table.yaml deleted file mode 100644 index f8324856dee356f2c72e1aac4d30987793d0e465..0000000000000000000000000000000000000000 --- a/resources/migrations/019_add_schema_column_to_table.yaml +++ /dev/null @@ -1,11 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 19 - author: camsaul - changes: - - addColumn: - tableName: metabase_table - columns: - - column: - name: schema - type: VARCHAR(256) diff --git a/resources/migrations/020_add_pulse_tables.yaml b/resources/migrations/020_add_pulse_tables.yaml deleted file mode 100644 index 7699ee8460f8b3cfd55f6cbeeba6be67c4b86e35..0000000000000000000000000000000000000000 --- a/resources/migrations/020_add_pulse_tables.yaml +++ /dev/null @@ -1,194 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 20 - author: agilliland - changes: - - createTable: - tableName: pulse - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: creator_id - type: int - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_pulse_ref_creator_id - deferrable: false - initiallyDeferred: false - - column: - name: name - type: varchar(254) - constraints: - nullable: false - - column: - name: public_perms - type: int - constraints: - nullable: false - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: pulse - indexName: idx_pulse_creator_id - columns: - column: - name: creator_id - - createTable: - tableName: pulse_card - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: pulse_id - type: int - constraints: - nullable: false - references: pulse(id) - foreignKeyName: fk_pulse_card_ref_pulse_id - deferrable: false - initiallyDeferred: false - - column: - name: card_id - type: int - constraints: - nullable: false - references: report_card(id) - foreignKeyName: fk_pulse_card_ref_card_id - deferrable: false - initiallyDeferred: false - - column: - name: position - type: int - constraints: - nullable: false - - createIndex: - tableName: pulse_card - indexName: idx_pulse_card_pulse_id - columns: - column: - name: pulse_id - - createIndex: - tableName: pulse_card - indexName: idx_pulse_card_card_id - columns: - column: - name: card_id - - createTable: - tableName: pulse_channel - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: pulse_id - type: int - constraints: - nullable: false - references: pulse(id) - foreignKeyName: fk_pulse_channel_ref_pulse_id - deferrable: false - initiallyDeferred: false - - column: - name: channel_type - type: varchar(32) - constraints: - nullable: false - - column: - name: details - type: text - constraints: - nullable: false - - column: - name: schedule_type - type: varchar(32) - constraints: - nullable: false - - column: - name: schedule_hour - type: int - constraints: - nullable: true - - column: - name: schedule_day - type: varchar(64) - constraints: - nullable: true - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: pulse_channel - indexName: idx_pulse_channel_pulse_id - columns: - column: - name: pulse_id - - createIndex: - tableName: pulse_channel - indexName: idx_pulse_channel_schedule_type - columns: - column: - name: schedule_type - - createTable: - tableName: pulse_channel_recipient - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: pulse_channel_id - type: int - constraints: - nullable: false - references: pulse_channel(id) - foreignKeyName: fk_pulse_channel_recipient_ref_pulse_channel_id - deferrable: false - initiallyDeferred: false - - column: - name: user_id - type: int - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_pulse_channel_recipient_ref_user_id - deferrable: false - initiallyDeferred: false - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/021_add_segment_table.yaml b/resources/migrations/021_add_segment_table.yaml deleted file mode 100644 index 8934a4b8469b2a2c251b7ce67658b39336a3ea86..0000000000000000000000000000000000000000 --- a/resources/migrations/021_add_segment_table.yaml +++ /dev/null @@ -1,81 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 21 - author: agilliland - changes: - - createTable: - tableName: segment - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: table_id - type: int - constraints: - nullable: false - references: metabase_table(id) - foreignKeyName: fk_segment_ref_table_id - deferrable: false - initiallyDeferred: false - - column: - name: creator_id - type: int - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_segment_ref_creator_id - deferrable: false - initiallyDeferred: false - - column: - name: name - type: varchar(254) - constraints: - nullable: false - - column: - name: description - type: text - constraints: - nullable: true - - column: - name: is_active - type: boolean - defaultValueBoolean: true - constraints: - nullable: false - - column: - name: definition - type: text - constraints: - nullable: false - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: segment - indexName: idx_segment_creator_id - columns: - column: - name: creator_id - - createIndex: - tableName: segment - indexName: idx_segment_table_id - columns: - column: - name: table_id - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/022_add_revision_message_field.yaml b/resources/migrations/022_add_revision_message_field.yaml deleted file mode 100644 index 9d19c46f715330c0d0ae4072d2790576bfe6e859..0000000000000000000000000000000000000000 --- a/resources/migrations/022_add_revision_message_field.yaml +++ /dev/null @@ -1,13 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 22 - author: agilliland - changes: - - addColumn: - tableName: revision - columns: - - column: - name: message - type: text - constraints: - nullable: true diff --git a/resources/migrations/023_modify_table_rows_to_bigint.yaml b/resources/migrations/023_modify_table_rows_to_bigint.yaml deleted file mode 100644 index 1fb8631e06f0032d86154ad0b055631c71a45809..0000000000000000000000000000000000000000 --- a/resources/migrations/023_modify_table_rows_to_bigint.yaml +++ /dev/null @@ -1,9 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 23 - author: agilliland - changes: - - modifyDataType: - tableName: metabase_table - columnName: rows - newDataType: BIGINT diff --git a/resources/migrations/024_add_dependency_table.yaml b/resources/migrations/024_add_dependency_table.yaml deleted file mode 100644 index cf7a0346459eb60d46d14fc862c867093f588a98..0000000000000000000000000000000000000000 --- a/resources/migrations/024_add_dependency_table.yaml +++ /dev/null @@ -1,69 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 24 - author: agilliland - changes: - - createTable: - tableName: dependency - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: model - type: varchar(32) - constraints: - nullable: false - - column: - name: model_id - type: int - constraints: - nullable: false - - column: - name: dependent_on_model - type: varchar(32) - constraints: - nullable: false - - column: - name: dependent_on_id - type: int - constraints: - nullable: false - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: dependency - indexName: idx_dependency_model - columns: - column: - name: model - - createIndex: - tableName: dependency - indexName: idx_dependency_model_id - columns: - column: - name: model_id - - createIndex: - tableName: dependency - indexName: idx_dependency_dependent_on_model - columns: - column: - name: dependent_on_model - - createIndex: - tableName: dependency - indexName: idx_dependency_dependent_on_id - columns: - column: - name: dependent_on_id - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/025_add_metric_table.yaml b/resources/migrations/025_add_metric_table.yaml deleted file mode 100644 index 7bd3be4218e13b64bf706959415062c0628c27e8..0000000000000000000000000000000000000000 --- a/resources/migrations/025_add_metric_table.yaml +++ /dev/null @@ -1,81 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 25 - author: agilliland - changes: - - createTable: - tableName: metric - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: table_id - type: int - constraints: - nullable: false - references: metabase_table(id) - foreignKeyName: fk_metric_ref_table_id - deferrable: false - initiallyDeferred: false - - column: - name: creator_id - type: int - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_metric_ref_creator_id - deferrable: false - initiallyDeferred: false - - column: - name: name - type: varchar(254) - constraints: - nullable: false - - column: - name: description - type: text - constraints: - nullable: true - - column: - name: is_active - type: boolean - defaultValueBoolean: true - constraints: - nullable: false - - column: - name: definition - type: text - constraints: - nullable: false - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: metric - indexName: idx_metric_creator_id - columns: - column: - name: creator_id - - createIndex: - tableName: metric - indexName: idx_metric_table_id - columns: - column: - name: table_id - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/026_add_database_is_full_sync_field.yaml b/resources/migrations/026_add_database_is_full_sync_field.yaml deleted file mode 100644 index 4c5a90d30e08e272924d88421c1d0cba40daa045..0000000000000000000000000000000000000000 --- a/resources/migrations/026_add_database_is_full_sync_field.yaml +++ /dev/null @@ -1,16 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 26 - author: agilliland - changes: - - addColumn: - tableName: metabase_database - columns: - - column: - name: is_full_sync - type: boolean - defaultValueBoolean: true - constraints: - nullable: false - - sql: - sql: update metabase_database set is_full_sync = true diff --git a/resources/migrations/027_add_dashcardseries_table.yaml b/resources/migrations/027_add_dashcardseries_table.yaml deleted file mode 100644 index 39d2d7c050c6d1538b013624d367f5f3b03f8f01..0000000000000000000000000000000000000000 --- a/resources/migrations/027_add_dashcardseries_table.yaml +++ /dev/null @@ -1,55 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 27 - author: agilliland - changes: - - createTable: - tableName: dashboardcard_series - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: dashboardcard_id - type: int - constraints: - nullable: false - references: report_dashboardcard(id) - foreignKeyName: fk_dashboardcard_series_ref_dashboardcard_id - deferrable: false - initiallyDeferred: false - - column: - name: card_id - type: int - constraints: - nullable: false - references: report_card(id) - foreignKeyName: fk_dashboardcard_series_ref_card_id - deferrable: false - initiallyDeferred: false - - column: - name: position - type: int - constraints: - nullable: false - - createIndex: - tableName: dashboardcard_series - indexName: idx_dashboardcard_series_dashboardcard_id - columns: - column: - name: dashboardcard_id - - createIndex: - tableName: dashboardcard_series - indexName: idx_dashboardcard_series_card_id - columns: - column: - name: card_id - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/028_add_user_is_qbnewb.yaml b/resources/migrations/028_add_user_is_qbnewb.yaml deleted file mode 100644 index 0b1c687cb09890fa82529b24207d65c0a3470483..0000000000000000000000000000000000000000 --- a/resources/migrations/028_add_user_is_qbnewb.yaml +++ /dev/null @@ -1,14 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 28 - author: agilliland - changes: - - addColumn: - tableName: core_user - columns: - - column: - name: is_qbnewb - type: boolean - defaultValueBoolean: true - constraints: - nullable: false diff --git a/resources/migrations/029_add_pulse_channel_schedule_frame.yaml b/resources/migrations/029_add_pulse_channel_schedule_frame.yaml deleted file mode 100644 index 1b290bd82a555dd67d928aca5d82bdca289a5321..0000000000000000000000000000000000000000 --- a/resources/migrations/029_add_pulse_channel_schedule_frame.yaml +++ /dev/null @@ -1,13 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 29 - author: agilliland - changes: - - addColumn: - tableName: pulse_channel - columns: - - column: - name: schedule_frame - type: varchar(32) - constraints: - nullable: true diff --git a/resources/migrations/030_add_field_visibility_type.yaml b/resources/migrations/030_add_field_visibility_type.yaml deleted file mode 100644 index 38ddac7d9ddd6ae7e3dbcf93390d40a90a199f7e..0000000000000000000000000000000000000000 --- a/resources/migrations/030_add_field_visibility_type.yaml +++ /dev/null @@ -1,20 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 30 - author: agilliland - changes: - - addColumn: - tableName: metabase_field - columns: - - column: - name: visibility_type - type: varchar(32) - constraints: - nullable: true - deferrable: false - initiallyDeferred: false - - addNotNullConstraint: - columnDataType: varchar(32) - columnName: visibility_type - defaultNullValue: unset - tableName: metabase_field diff --git a/resources/migrations/031_add_field_fk_target.yaml b/resources/migrations/031_add_field_fk_target.yaml deleted file mode 100644 index 0c109941176bff4771a4c3ec8d54cb2fc8dc602e..0000000000000000000000000000000000000000 --- a/resources/migrations/031_add_field_fk_target.yaml +++ /dev/null @@ -1,15 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 31 - author: agilliland - changes: - - addColumn: - tableName: metabase_field - columns: - - column: - name: fk_target_field_id - type: int - constraints: - nullable: true - deferrable: false - initiallyDeferred: false diff --git a/resources/migrations/032_add_label_and_card_label_tables.yaml b/resources/migrations/032_add_label_and_card_label_tables.yaml deleted file mode 100644 index 60a321cdf2a52cab27b1e8719bb299f1d410c14a..0000000000000000000000000000000000000000 --- a/resources/migrations/032_add_label_and_card_label_tables.yaml +++ /dev/null @@ -1,91 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 32 - author: camsaul - changes: - ######################################## label table ######################################## - - createTable: - tableName: label - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: name - type: VARCHAR(254) - constraints: - nullable: false - - column: - name: slug - type: VARCHAR(254) - constraints: - nullable: false - unique: true - - column: - name: icon - type: VARCHAR(128) - - createIndex: - tableName: label - indexName: idx_label_slug - columns: - column: - name: slug - ######################################## card_label table ######################################## - - createTable: - tableName: card_label - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: card_id - type: int - constraints: - nullable: false - references: report_card(id) - foreignKeyName: fk_card_label_ref_card_id - deferrable: false - initiallyDeferred: false - - column: - name: label_id - type: int - constraints: - nullable: false - references: label(id) - foreignKeyName: fk_card_label_ref_label_id - deferrable: false - initiallyDeferred: false - - addUniqueConstraint: - tableName: card_label - columnNames: card_id, label_id - constraintName: unique_card_label_card_id_label_id - - createIndex: - tableName: card_label - indexName: idx_card_label_card_id - columns: - column: - name: card_id - - createIndex: - tableName: card_label - indexName: idx_card_label_label_id - columns: - column: - name: label_id - ######################################## add archived column to report_card ######################################## - - addColumn: - tableName: report_card - columns: - - column: - name: archived - type: boolean - defaultValueBoolean: false - constraints: - nullable: false diff --git a/resources/migrations/033_add_physical_schema_tables.yaml b/resources/migrations/033_add_physical_schema_tables.yaml deleted file mode 100644 index 9a19835461de6e5fe586ea7fac9fc508cae4dd69..0000000000000000000000000000000000000000 --- a/resources/migrations/033_add_physical_schema_tables.yaml +++ /dev/null @@ -1,172 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 32 - author: agilliland - changes: - - createTable: - tableName: raw_table - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: database_id - type: int - constraints: - nullable: false - references: metabase_database(id) - foreignKeyName: fk_rawtable_ref_database - deferrable: false - initiallyDeferred: false - - column: - name: active - type: boolean - constraints: - nullable: false - - column: - name: schema - type: varchar(255) - constraints: - nullable: true - - column: - name: name - type: varchar(255) - constraints: - nullable: false - - column: - name: details - type: text - constraints: - nullable: false - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: raw_table - indexName: idx_rawtable_database_id - columns: - column: - name: database_id - - addUniqueConstraint: - tableName: raw_table - columnNames: database_id, schema, name - constraintName: uniq_raw_table_db_schema_name - - createTable: - tableName: raw_column - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: raw_table_id - type: int - constraints: - nullable: false - references: raw_table(id) - foreignKeyName: fk_rawcolumn_tableid_ref_rawtable - deferrable: false - initiallyDeferred: false - - column: - name: active - type: boolean - constraints: - nullable: false - - column: - name: name - type: varchar(255) - constraints: - nullable: false - - column: - name: column_type - type: varchar(128) - constraints: - nullable: true - - column: - name: is_pk - type: boolean - constraints: - nullable: false - - column: - name: fk_target_column_id - type: int - constraints: - nullable: true - references: raw_column(id) - foreignKeyName: fk_rawcolumn_fktarget_ref_rawcolumn - deferrable: false - initiallyDeferred: false - - column: - name: details - type: text - constraints: - nullable: false - - column: - name: created_at - type: DATETIME - constraints: - nullable: false - - column: - name: updated_at - type: DATETIME - constraints: - nullable: false - - createIndex: - tableName: raw_column - indexName: idx_rawcolumn_raw_table_id - columns: - column: - name: raw_table_id - - addUniqueConstraint: - tableName: raw_column - columnNames: raw_table_id, name - constraintName: uniq_raw_column_table_name - - addColumn: - tableName: metabase_table - columns: - - column: - name: raw_table_id - type: int - constraints: - nullable: true - deferrable: false - initiallyDeferred: false - - addColumn: - tableName: metabase_field - columns: - - column: - name: raw_column_id - type: int - constraints: - nullable: true - deferrable: false - initiallyDeferred: false - - addColumn: - tableName: metabase_field - columns: - - column: - name: last_analyzed - type: DATETIME - constraints: - nullable: true - deferrable: false - initiallyDeferred: false - - modifySql: - dbms: postgresql - replace: - replace: WITHOUT - with: WITH diff --git a/resources/migrations/034_add_pulse_channel_enabled_field.yaml b/resources/migrations/034_add_pulse_channel_enabled_field.yaml deleted file mode 100644 index ed17c22c2396e28cc008704605c186f27d7ab4f0..0000000000000000000000000000000000000000 --- a/resources/migrations/034_add_pulse_channel_enabled_field.yaml +++ /dev/null @@ -1,15 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 34 - author: tlrobinson - changes: - ######################################## add enabled column to pulse_channel ######################################## - - addColumn: - tableName: pulse_channel - columns: - - column: - name: enabled - type: boolean - defaultValueBoolean: true - constraints: - nullable: false diff --git a/resources/migrations/035_modify_setting_value_length.yaml b/resources/migrations/035_modify_setting_value_length.yaml deleted file mode 100644 index 3ca7b3ba6276b50c1799c76b5fbc63b58d3cb0fb..0000000000000000000000000000000000000000 --- a/resources/migrations/035_modify_setting_value_length.yaml +++ /dev/null @@ -1,12 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 35 - author: agilliland - changes: - - modifyDataType: - tableName: setting - columnName: value - newDataType: TEXT - - addNotNullContstraint: - tableName: setting - columnNames: value diff --git a/resources/migrations/036_add_dashboard_filters_columns.yaml b/resources/migrations/036_add_dashboard_filters_columns.yaml deleted file mode 100644 index 706b300246f7d75bddb4976230f22915ea0bc2e1..0000000000000000000000000000000000000000 --- a/resources/migrations/036_add_dashboard_filters_columns.yaml +++ /dev/null @@ -1,35 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 36 - author: agilliland - changes: - - addColumn: - tableName: report_dashboard - columns: - - column: - name: parameters - type: text - constraints: - nullable: true - deferrable: false - initiallyDeferred: false - - addNotNullConstraint: - columnDataType: text - columnName: parameters - defaultNullValue: '[]' - tableName: report_dashboard - - addColumn: - tableName: report_dashboardcard - columns: - - column: - name: parameter_mappings - type: text - constraints: - nullable: true - deferrable: false - initiallyDeferred: false - - addNotNullConstraint: - columnDataType: text - columnName: parameter_mappings - defaultNullValue: '[]' - tableName: report_dashboardcard diff --git a/resources/migrations/037_add_query_hash_and_indexes.yaml b/resources/migrations/037_add_query_hash_and_indexes.yaml deleted file mode 100644 index 22bd1799130f9a32a3c3854d34ce072fec401645..0000000000000000000000000000000000000000 --- a/resources/migrations/037_add_query_hash_and_indexes.yaml +++ /dev/null @@ -1,30 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 37 - author: tlrobinson - changes: - - addColumn: - tableName: query_queryexecution - columns: - - column: - name: query_hash - type: int - constraints: - nullable: true - - addNotNullConstraint: - tableName: query_queryexecution - columnName: query_hash - columnDataType: int - defaultNullValue: 0 - - createIndex: - tableName: query_queryexecution - indexName: idx_query_queryexecution_query_hash - columns: - column: - name: query_hash - - createIndex: - tableName: query_queryexecution - indexName: idx_query_queryexecution_started_at - columns: - column: - name: started_at diff --git a/resources/migrations/038_getting_started_guide.yaml b/resources/migrations/038_getting_started_guide.yaml deleted file mode 100644 index 93433a69dd3591e4e35d7c838df0d54e9abb3293..0000000000000000000000000000000000000000 --- a/resources/migrations/038_getting_started_guide.yaml +++ /dev/null @@ -1,191 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 38 - author: camsaul - changes: - ######################################## Add "points_of_interest" metadata column to various models ######################################## - - addColumn: - tableName: metabase_database - columns: - - column: - name: points_of_interest - type: text - - addColumn: - tableName: metabase_table - columns: - - column: - name: points_of_interest - type: text - - addColumn: - tableName: metabase_field - columns: - - column: - name: points_of_interest - type: text - - addColumn: - tableName: report_dashboard - columns: - - column: - name: points_of_interest - type: text - - addColumn: - tableName: metric - columns: - - column: - name: points_of_interest - type: text - - addColumn: - tableName: segment - columns: - - column: - name: points_of_interest - type: text - ######################################## Add "caveats" metadata column to various models ######################################## - - addColumn: - tableName: metabase_database - columns: - - column: - name: caveats - type: text - - addColumn: - tableName: metabase_table - columns: - - column: - name: caveats - type: text - - addColumn: - tableName: metabase_field - columns: - - column: - name: caveats - type: text - - addColumn: - tableName: report_dashboard - columns: - - column: - name: caveats - type: text - - addColumn: - tableName: metric - columns: - - column: - name: caveats - type: text - - addColumn: - tableName: segment - columns: - - column: - name: caveats - type: text - ######################################## Add "how_is_this_calculated" to metric ######################################## - - addColumn: - tableName: metric - columns: - - column: - name: how_is_this_calculated - type: text - ######################################## Add "most important dashboard" (0 or 1 dashboards) ######################################## - - addColumn: - tableName: report_dashboard - columns: - - column: - name: show_in_getting_started - type: boolean - defaultValueBoolean: false - constraints: - nullable: false - - createIndex: - tableName: report_dashboard - indexName: idx_report_dashboard_show_in_getting_started - columns: - column: - name: show_in_getting_started - ######################################## Add "most important metrics" (0+ metrics) ######################################## - - addColumn: - tableName: metric - columns: - - column: - name: show_in_getting_started - type: boolean - defaultValueBoolean: false - constraints: - nullable: false - - createIndex: - tableName: metric - indexName: idx_metric_show_in_getting_started - columns: - column: - name: show_in_getting_started - ######################################## Add "most important tables (0+ tables) ######################################## - - addColumn: - tableName: metabase_table - columns: - - column: - name: show_in_getting_started - type: boolean - defaultValueBoolean: false - constraints: - nullable: false - - createIndex: - tableName: metabase_table - indexName: idx_metabase_table_show_in_getting_started - columns: - column: - name: show_in_getting_started - ######################################## Add "most important segments" (0+ segments) ######################################## - - addColumn: - tableName: segment - columns: - - column: - name: show_in_getting_started - type: boolean - defaultValueBoolean: false - constraints: - nullable: false - - createIndex: - tableName: segment - indexName: idx_segment_show_in_getting_started - columns: - column: - name: show_in_getting_started - ######################################## Add "metric_important_field" table ######################################## - - createTable: - tableName: metric_important_field - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: metric_id - type: int - constraints: - nullable: false - references: metric(id) - foreignKeyName: fk_metric_important_field_metric_id - - column: - name: field_id - type: int - constraints: - nullable: false - references: metabase_field(id) - foreignKeyName: fk_metric_important_field_metabase_field_id - - addUniqueConstraint: - tableName: metric_important_field - columnNames: metric_id, field_id - constraintName: unique_metric_important_field_metric_id_field_id - - createIndex: - tableName: metric_important_field - indexName: idx_metric_important_field_metric_id - columns: - column: - name: metric_id - - createIndex: - tableName: metric_important_field - indexName: idx_metric_important_field_field_id - columns: - column: - name: field_id diff --git a/resources/migrations/039_add_user_google_auth_column.yaml b/resources/migrations/039_add_user_google_auth_column.yaml deleted file mode 100644 index 159cb9acdeb1f5cbe577efe8c0da172585e7daf2..0000000000000000000000000000000000000000 --- a/resources/migrations/039_add_user_google_auth_column.yaml +++ /dev/null @@ -1,14 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 39 - author: camsaul - changes: - - addColumn: - tableName: core_user - columns: - - column: - name: google_auth - type: boolean - defaultValueBoolean: false - constraints: - nullable: false diff --git a/resources/migrations/040_permissions_v1.yaml b/resources/migrations/040_permissions_v1.yaml deleted file mode 100644 index e711ef94b6313720d287a8bc76ae6c7c30e71d91..0000000000000000000000000000000000000000 --- a/resources/migrations/040_permissions_v1.yaml +++ /dev/null @@ -1,150 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 40 - author: camsaul - changes: - ############################################################ add PermissionsGroup table ############################################################ - - createTable: - tableName: permissions_group - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - # TODO - it would be nice to make this a case-insensitive unique constraint / index? - - column: - name: name - type: varchar(255) - constraints: - nullable: false - unique: true - uniqueConstraintName: unique_permissions_group_name - - createIndex: - tableName: permissions_group - indexName: idx_permissions_group_name - columns: - column: - name: name - ############################################################ add PermissionsGroupMembership table ############################################################ - - createTable: - tableName: permissions_group_membership - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: user_id - type: int - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_permissions_group_membership_user_id - - column: - name: group_id - type: int - constraints: - nullable: false - references: permissions_group(id) - foreignKeyName: fk_permissions_group_group_id - - addUniqueConstraint: - tableName: permissions_group_membership - columnNames: user_id, group_id - constraintName: unique_permissions_group_membership_user_id_group_id - # for things like all users in a given group - - createIndex: - tableName: permissions_group_membership - indexName: idx_permissions_group_membership_group_id - columns: - column: - name: group_id - # for things like all groups a user belongs to - - createIndex: - tableName: permissions_group_membership - indexName: idx_permissions_group_membership_user_id - columns: - column: - name: user_id - # for things like is given user a member of a given group (TODO - not sure we need this) - - createIndex: - tableName: permissions_group_membership - indexName: idx_permissions_group_membership_group_id_user_id - columns: - column: - name: group_id - column: - name: user_id - ############################################################ add Permissions table ############################################################ - - createTable: - tableName: permissions - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: object - type: varchar(254) - constraints: - nullable: false - - column: - name: group_id - type: int - constraints: - nullable: false - references: permissions_group(id) - foreignKeyName: fk_permissions_group_id - - createIndex: - tableName: permissions - indexName: idx_permissions_group_id - columns: - column: - name: group_id - - createIndex: - tableName: permissions - indexName: idx_permissions_object - columns: - column: - name: object - - createIndex: - tableName: permissions - indexName: idx_permissions_group_id_object - columns: - column: - name: group_id - column: - name: object - - addUniqueConstraint: - tableName: permissions - columnNames: group_id, object - ############################################################ Tweaks to metabase_table ############################################################ - # Modify the length of metabase_table.schema from 256 -> 254 - # It turns out MySQL InnoDB indecies have to be 767 bytes or less (at least for older versions of MySQL) - # and 'utf8' text columns can use up to 3 bytes per character in MySQL -- see http://stackoverflow.com/a/22515986/1198455 - # So 256 * 3 = 768 bytes (too large to index / add unique constraints) - # Drop this to 254; 254 * 3 = 762, which should give us room to index it along with a 4-byte integer as well if need be - # Hoping this doesn't break anyone's existing databases. Hopefully there aren't any schemas that are 255 or 256 bytes long out there; any longer - # and it would have already broke; any shorter and there's not problem. - # Anyway, better to break it now than to leave it as-is and have and break permissions where the columns have to be 254 characters wide - - modifyDataType: - tableName: metabase_table - columnName: schema - newDataType: varchar(254) - # Add index: this is for doing things like getting all the tables that belong to a given schema - - createIndex: - tableName: metabase_table - indexName: idx_metabase_table_db_id_schema - columns: - column: - name: db_id - column: - name: schema diff --git a/resources/migrations/041_drop_field_field_type.yaml b/resources/migrations/041_drop_field_field_type.yaml deleted file mode 100644 index 8b40de6dc7421bdf5a0e790d2d2f4e537a93ac48..0000000000000000000000000000000000000000 --- a/resources/migrations/041_drop_field_field_type.yaml +++ /dev/null @@ -1,24 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 41 - author: camsaul - changes: - - dropColumn: - tableName: metabase_field - columnName: field_type - - addDefaultValue: - tableName: metabase_field - columnName: active - defaultValueBoolean: true - - addDefaultValue: - tableName: metabase_field - columnName: preview_display - defaultValueBoolean: true - - addDefaultValue: - tableName: metabase_field - columnName: position - defaultValueNumeric: 0 - - addDefaultValue: - tableName: metabase_field - columnName: visibility_type - defaultValue: "normal" diff --git a/resources/migrations/042_remove_unused_tables.yaml b/resources/migrations/042_remove_unused_tables.yaml deleted file mode 100644 index e4dd9e01e382bb1d8715215af990ed1508c4daef..0000000000000000000000000000000000000000 --- a/resources/migrations/042_remove_unused_tables.yaml +++ /dev/null @@ -1,45 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 42 - author: camsaul - changes: - - dropForeignKeyConstraint: - baseTableName: query_queryexecution - constraintName: fk_queryexecution_ref_query_id - - dropColumn: - tableName: query_queryexecution - columnName: query_id - - dropColumn: - tableName: core_user - columnName: is_staff - - dropColumn: - tableName: metabase_database - columnName: organization_id - - dropColumn: - tableName: report_card - columnName: organization_id - - dropColumn: - tableName: report_dashboard - columnName: organization_id - - dropTable: - tableName: annotation_annotation - - dropTable: - tableName: core_permissionsviolation - - dropTable: - tableName: core_userorgperm - - dropTable: - tableName: core_organization - - dropTable: - tableName: metabase_foreignkey - - dropTable: - tableName: metabase_tablesegment - - dropTable: - tableName: query_query - - dropTable: - tableName: report_dashboardsubscription - - dropTable: - tableName: report_emailreport_recipients - - dropTable: - tableName: report_emailreportexecutions - - dropTable: - tableName: report_emailreport diff --git a/resources/migrations/043_add_permissions_revision_table.yaml b/resources/migrations/043_add_permissions_revision_table.yaml deleted file mode 100644 index 59ddfd4e511d05e4db438c8af3da2a87a2ebec59..0000000000000000000000000000000000000000 --- a/resources/migrations/043_add_permissions_revision_table.yaml +++ /dev/null @@ -1,48 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 43 - author: camsaul - validCheckSum: 7:b20750a949504e93efced32877a4488f - validCheckSum: 7:dbc18c8ca697fc335869f0ed0eb5f4cb - changes: - - createTable: - tableName: permissions_revision - remarks: 'Used to keep track of changes made to permissions.' - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: before - type: text - remarks: 'Serialized JSON of the permissions before the changes.' - constraints: - nullable: false - - column: - name: after - type: text - remarks: 'Serialized JSON of the permissions after the changes.' - constraints: - nullable: false - - column: - name: user_id - type: int - remarks: 'The ID of the admin who made this set of changes.' - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_permissions_revision_user_id - - column: - name: created_at - type: datetime - remarks: 'The timestamp of when these changes were made.' - constraints: - nullable: false - - column: - name: remark - type: text - remarks: 'Optional remarks explaining why these changes were made.' diff --git a/resources/migrations/044_remove_public_perms_columns.yaml b/resources/migrations/044_remove_public_perms_columns.yaml deleted file mode 100644 index 84586c975f84d870a2fad2b90848606daf8b489c..0000000000000000000000000000000000000000 --- a/resources/migrations/044_remove_public_perms_columns.yaml +++ /dev/null @@ -1,14 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 44 - author: camsaul - changes: - - dropColumn: - tableName: report_card - columnName: public_perms - - dropColumn: - tableName: report_dashboard - columnName: public_perms - - dropColumn: - tableName: pulse - columnName: public_perms diff --git a/resources/migrations/045_add_dashcard_visualization_settings_field.yaml b/resources/migrations/045_add_dashcard_visualization_settings_field.yaml deleted file mode 100644 index 75414b151dd6ee8a6d45ddb9086df75b40151d45..0000000000000000000000000000000000000000 --- a/resources/migrations/045_add_dashcard_visualization_settings_field.yaml +++ /dev/null @@ -1,16 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 45 - author: tlrobinson - changes: - - addColumn: - tableName: report_dashboardcard - columns: - - column: - name: visualization_settings - type: text - - addNotNullConstraint: - tableName: report_dashboardcard - columnName: visualization_settings - columnDataType: text - defaultNullValue: '{}' diff --git a/resources/migrations/046_add_not_null_constraints_for_dashboard_card_row_col.yaml b/resources/migrations/046_add_not_null_constraints_for_dashboard_card_row_col.yaml deleted file mode 100644 index 24dd461d8b5669a668474932bd7ca3fb90e342e2..0000000000000000000000000000000000000000 --- a/resources/migrations/046_add_not_null_constraints_for_dashboard_card_row_col.yaml +++ /dev/null @@ -1,23 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 46 - author: camsaul - changes: - - addNotNullConstraint: - tableName: report_dashboardcard - columnName: row - columnDataType: integer - defaultNullValue: 0 - - addNotNullConstraint: - tableName: report_dashboardcard - columnName: col - columnDataType: integer - defaultNullValue: 0 - - addDefaultValue: - tableName: report_dashboardcard - columnName: row - defaultValueNumeric: 0 - - addDefaultValue: - tableName: report_dashboardcard - columnName: col - defaultValueNumeric: 0 diff --git a/resources/migrations/047_add_collection_table.yaml b/resources/migrations/047_add_collection_table.yaml deleted file mode 100644 index 61d72ff455caca48be9c50d9f2f053aa378a1953..0000000000000000000000000000000000000000 --- a/resources/migrations/047_add_collection_table.yaml +++ /dev/null @@ -1,70 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 47 - author: camsaul - changes: - ######################################## collection table ######################################## - - createTable: - tableName: collection - remarks: 'Collections are an optional way to organize Cards and handle permissions for them.' - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: name - type: text - remarks: 'The unique, user-facing name of this Collection.' - constraints: - nullable: false - - column: - name: slug - type: varchar(254) - remarks: 'URL-friendly, sluggified, indexed version of name.' - constraints: - nullable: false - unique: true - - column: - name: description - type: text - remarks: 'Optional description for this Collection.' - - column: - name: color - type: char(7) - remarks: 'Seven-character hex color for this Collection, including the preceding hash sign.' - constraints: - nullable: false - - column: - name: archived - type: boolean - remarks: 'Whether this Collection has been archived and should be hidden from users.' - defaultValueBoolean: false - constraints: - nullable: false - - createIndex: - tableName: collection - indexName: idx_collection_slug - columns: - column: - name: slug - ######################################## add collection_id to report_card ######################################## - - addColumn: - tableName: report_card - columns: - - column: - name: collection_id - type: int - remarks: 'Optional ID of Collection this Card belongs to.' - constraints: - references: collection(id) - foreignKeyName: fk_card_collection_id - - createIndex: - tableName: report_card - indexName: idx_card_collection_id - columns: - column: - name: collection_id diff --git a/resources/migrations/048_add_collection_revision_table.yaml b/resources/migrations/048_add_collection_revision_table.yaml deleted file mode 100644 index 1be0134d81d42f154f8804a5a51f1fbaecc3db54..0000000000000000000000000000000000000000 --- a/resources/migrations/048_add_collection_revision_table.yaml +++ /dev/null @@ -1,46 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 48 - author: camsaul - changes: - - createTable: - tableName: collection_revision - remarks: 'Used to keep track of changes made to collections.' - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: before - type: text - remarks: 'Serialized JSON of the collections graph before the changes.' - constraints: - nullable: false - - column: - name: after - type: text - remarks: 'Serialized JSON of the collections graph after the changes.' - constraints: - nullable: false - - column: - name: user_id - type: int - remarks: 'The ID of the admin who made this set of changes.' - constraints: - nullable: false - references: core_user(id) - foreignKeyName: fk_collection_revision_user_id - - column: - name: created_at - type: datetime - remarks: 'The timestamp of when these changes were made.' - constraints: - nullable: false - - column: - name: remark - type: text - remarks: 'Optional remarks explaining why these changes were made.' diff --git a/resources/migrations/049_add_public_link_columns.yaml b/resources/migrations/049_add_public_link_columns.yaml deleted file mode 100644 index 8f25196a58fcb1778ed1b5426c02d8439933718d..0000000000000000000000000000000000000000 --- a/resources/migrations/049_add_public_link_columns.yaml +++ /dev/null @@ -1,56 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 49 - author: camsaul - changes: - ######################################## Card public_uuid & indecies ######################################## - - addColumn: - tableName: report_card - columns: - - column: - name: public_uuid - type: char(36) - remarks: 'Unique UUID used to in publically-accessible links to this Card.' - constraints: - unique: true - - column: - name: made_public_by_id - type: int - remarks: 'The ID of the User who first publically shared this Card.' - constraints: - references: core_user(id) - foreignKeyName: fk_card_made_public_by_id - - createIndex: - tableName: report_card - indexName: idx_card_public_uuid - columns: - column: - name: public_uuid - ######################################## Dashboard public_uuid & indecies ######################################## - - addColumn: - tableName: report_dashboard - columns: - - column: - name: public_uuid - type: char(36) - remarks: 'Unique UUID used to in publically-accessible links to this Dashboard.' - constraints: - unique: true - - column: - name: made_public_by_id - type: int - remarks: 'The ID of the User who first publically shared this Dashboard.' - constraints: - references: core_user(id) - foreignKeyName: fk_dashboard_made_public_by_id - - createIndex: - tableName: report_dashboard - indexName: idx_dashboard_public_uuid - columns: - column: - name: public_uuid - ######################################## make query_queryexecution.executor_id nullable ######################################## - - dropNotNullConstraint: - tableName: query_queryexecution - columnName: executor_id - columnDataType: int diff --git a/resources/migrations/050_add_embedding_columns.yaml b/resources/migrations/050_add_embedding_columns.yaml deleted file mode 100644 index a171e296aee3f3e8170c2d7a8d0ebe03c8a2781f..0000000000000000000000000000000000000000 --- a/resources/migrations/050_add_embedding_columns.yaml +++ /dev/null @@ -1,35 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 50 - author: camsaul - changes: - ######################################## new Card columns ######################################## - - addColumn: - tableName: report_card - columns: - - column: - name: enable_embedding - type: boolean - remarks: 'Is this Card allowed to be embedded in different websites (using a signed JWT)?' - defaultValueBoolean: false - constraints: - nullable: false - - column: - name: embedding_params - type: text - remarks: 'Serialized JSON containing information about required parameters that must be supplied when embedding this Card.' - ######################################## new Card columns ######################################## - - addColumn: - tableName: report_dashboard - columns: - - column: - name: enable_embedding - type: boolean - remarks: 'Is this Dashboard allowed to be embedded in different websites (using a signed JWT)?' - defaultValueBoolean: false - constraints: - nullable: false - - column: - name: embedding_params - type: text - remarks: 'Serialized JSON containing information about required parameters that must be supplied when embedding this Dashboard.' diff --git a/resources/migrations/051_add_new_query_execution_table.yaml b/resources/migrations/051_add_new_query_execution_table.yaml deleted file mode 100644 index 8b2c2cf52e61ffdf06474b03b798719d197571a0..0000000000000000000000000000000000000000 --- a/resources/migrations/051_add_new_query_execution_table.yaml +++ /dev/null @@ -1,91 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 51 - author: camsaul - changes: - - createTable: - tableName: query_execution - remarks: 'A log of executed queries, used for calculating historic execution times, auditing, and other purposes.' - columns: - - column: - name: id - type: int - autoIncrement: true - constraints: - primaryKey: true - nullable: false - - column: - name: hash - type: binary(32) - remarks: 'The hash of the query dictionary. This is a 256-bit SHA3 hash of the query.' - constraints: - nullable: false - - column: - name: started_at - type: datetime - remarks: 'Timestamp of when this query started running.' - constraints: - nullable: false - - column: - name: running_time - type: integer - remarks: 'The time, in milliseconds, this query took to complete.' - constraints: - nullable: false - - column: - name: result_rows - type: integer - remarks: 'Number of rows in the query results.' - constraints: - nullable: false - - column: - name: native - type: boolean - remarks: 'Whether the query was a native query, as opposed to an MBQL one (e.g., created with the GUI).' - constraints: - nullable: false - - column: - name: context - type: varchar(32) - remarks: 'Short string specifying how this query was executed, e.g. in a Dashboard or Pulse.' - - column: - name: error - type: text - remarks: 'Error message returned by failed query, if any.' - # The following columns are foreign keys, but we don't keep FK constraints on them for a few reasons: - # - We don't want to keep indexes on these columns since they wouldn't be generally useful and for size and performance reasons - # - If a related object (e.g. a Dashboard) is deleted, we don't want to delete the related entries in the QueryExecution log. - # We could do something like make the constraint ON DELETE SET NULL, but that would require a full table scan to handle; - # If the QueryExecution log became tens of millions of rows large it would take a very long time to scan and update records - - column: - name: executor_id - type: integer - remarks: 'The ID of the User who triggered this query execution, if any.' - - column: - name: card_id - type: integer - remarks: 'The ID of the Card (Question) associated with this query execution, if any.' - - column: - name: dashboard_id - type: integer - remarks: 'The ID of the Dashboard associated with this query execution, if any.' - - column: - name: pulse_id - type: integer - remarks: 'The ID of the Pulse associated with this query execution, if any.' - # For things like auditing recently executed queries - - createIndex: - tableName: query_execution - indexName: idx_query_execution_started_at - columns: - column: - name: started_at - # For things like seeing the 10 most recent executions of a certain query - - createIndex: - tableName: query_execution - indexName: idx_query_execution_query_hash_started_at - columns: - column: - name: query_hash - column: - name: started_at diff --git a/resources/migrations/052_add_query_cache_table.yaml b/resources/migrations/052_add_query_cache_table.yaml deleted file mode 100644 index e21e19f5047f4a544217a8faf4d822d624cae3b0..0000000000000000000000000000000000000000 --- a/resources/migrations/052_add_query_cache_table.yaml +++ /dev/null @@ -1,49 +0,0 @@ -databaseChangeLog: - - property: - name: blob.type - value: blob - dbms: mysql,h2 - - property: - name: blob.type - value: bytea - dbms: postgresql - - changeSet: - id: 52 - author: camsaul - changes: - - createTable: - tableName: query_cache - remarks: 'Cached results of queries are stored here when using the DB-based query cache.' - columns: - - column: - name: query_hash - type: binary(32) - remarks: 'The hash of the query dictionary. (This is a 256-bit SHA3 hash of the query dict).' - constraints: - primaryKey: true - nullable: false - - column: - name: updated_at - type: datetime - remarks: 'The timestamp of when these query results were last refreshed.' - constraints: - nullable: false - - column: - name: results - type: ${blob.type} - remarks: 'Cached, compressed results of running the query with the given hash.' - constraints: - nullable: false - - createIndex: - tableName: query_cache - indexName: idx_query_cache_updated_at - columns: - column: - name: updated_at - - addColumn: - tableName: report_card - columns: - - column: - name: cache_ttl - type: int - remarks: 'The maximum time, in seconds, to return cached results for this Card rather than running a new query.' diff --git a/resources/migrations/053_add_query_table.yaml b/resources/migrations/053_add_query_table.yaml deleted file mode 100644 index 772de999cb50a8a43200f4f043ff3034ed93d425..0000000000000000000000000000000000000000 --- a/resources/migrations/053_add_query_table.yaml +++ /dev/null @@ -1,22 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 53 - author: camsaul - changes: - - createTable: - tableName: query - remarks: 'Information (such as average execution time) for different queries that have been previously ran.' - columns: - - column: - name: query_hash - type: binary(32) - remarks: 'The hash of the query dictionary. (This is a 256-bit SHA3 hash of the query dict.)' - constraints: - primaryKey: true - nullable: false - - column: - name: average_execution_time - type: int - remarks: 'Average execution time for the query, round to nearest number of milliseconds. This is updated as a rolling average.' - constraints: - nullable: false diff --git a/resources/migrations/054_add_pulse_skip_if_empty.yaml b/resources/migrations/054_add_pulse_skip_if_empty.yaml deleted file mode 100644 index 054cf11db5e464d73a2e5e815b27debf943896dc..0000000000000000000000000000000000000000 --- a/resources/migrations/054_add_pulse_skip_if_empty.yaml +++ /dev/null @@ -1,15 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 54 - author: tlrobinson - changes: - - addColumn: - tableName: pulse - remarks: 'Skip a scheduled Pulse if none of its questions have any results' - columns: - - column: - name: skip_if_empty - type: boolean - defaultValueBoolean: false - constraints: - nullable: false diff --git a/src/metabase/api/card.clj b/src/metabase/api/card.clj index 0abd7ad37015666f4dc86d6e107fc87ea6d5a5eb..e27c8c855ce6dcc1e2143a40bf4663287d34e84f 100644 --- a/src/metabase/api/card.clj +++ b/src/metabase/api/card.clj @@ -3,6 +3,7 @@ [clojure.tools.logging :as log] [cheshire.core :as json] [compojure.core :refer [GET POST DELETE PUT]] + [ring.util.codec :as codec] [schema.core :as s] (toucan [db :as db] [hydrate :refer [hydrate]]) @@ -133,8 +134,18 @@ (defn- ^:deprecated card-has-label? [label-slug card] (contains? (set (map :slug (:labels card))) label-slug)) +(defn- collection-slug->id [collection-slug] + (when (seq collection-slug) + ;; special characters in the slugs are always URL-encoded when stored in the DB, e.g. + ;; "Obsługa klienta" becomes "obs%C5%82uga_klienta". But for some weird reason sometimes the slug is passed in like + ;; "obsługa_klientaa" (not URL-encoded) so go ahead and URL-encode the input as well so we can match either case + (check-404 (db/select-one-id Collection + {:where [:or [:= :slug collection-slug] + [:= :slug (codec/url-encode collection-slug)]]})))) + ;; TODO - do we need to hydrate the cards' collections as well? -(defn- cards-for-filter-option [filter-option model-id label collection] +(defn- cards-for-filter-option [filter-option model-id label collection-slug] + (println "collection-slug:" collection-slug) ; NOCOMMIT (let [cards (-> ((filter-option->fn (or filter-option :all)) model-id) (hydrate :creator :collection) hydrate-labels @@ -142,11 +153,10 @@ ;; Since labels and collections are hydrated in Clojure-land we need to wait until this point to apply label/collection filtering if applicable ;; COLLECTION can optionally be an empty string which is used to repre (filter (cond - collection (let [collection-id (when (seq collection) - (check-404 (db/select-one-id Collection :slug collection)))] - (comp (partial = collection-id) :collection_id)) - (seq label) (partial card-has-label? label) - :else identity) + collection-slug (let [collection-id (collection-slug->id collection-slug)] + (comp (partial = collection-id) :collection_id)) + (seq label) (partial card-has-label? label) + :else identity) cards))) @@ -232,7 +242,7 @@ {name (s/maybe su/NonBlankString) dataset_query (s/maybe su/Map) display (s/maybe su/NonBlankString) - description (s/maybe su/NonBlankString) + description (s/maybe s/Str) visualization_settings (s/maybe su/Map) archived (s/maybe s/Bool) enable_embedding (s/maybe s/Bool) @@ -259,12 +269,17 @@ (check-superuser)) ;; ok, now save the Card (db/update! Card id - (merge (when (contains? body :collection_id) - {:collection_id collection_id}) - (into {} (for [k [:dataset_query :description :display :name :visualization_settings :archived :enable_embedding :embedding_params] - :let [v (k body)] - :when (not (nil? v))] - {k v})))) + (merge + ;; `collection_id` and `description` can be `nil` (in order to unset them) + (when (contains? body :collection_id) + {:collection_id collection_id}) + (when (contains? body :description) + {:description description}) + ;; other values should only be modified if they're passed in as non-nil + (into {} (for [k [:dataset_query :display :name :visualization_settings :archived :enable_embedding :embedding_params] + :let [v (k body)] + :when (not (nil? v))] + {k v})))) (let [event (cond ;; card was archived (and archived diff --git a/src/metabase/api/dashboard.clj b/src/metabase/api/dashboard.clj index d252c6542321c5023ded495ffe5342a03c1b2d5a..e965621b68f40904f7e45b873a7811c5828fbc40 100644 --- a/src/metabase/api/dashboard.clj +++ b/src/metabase/api/dashboard.clj @@ -73,7 +73,7 @@ but to change the value of `enable_embedding` you must be a superuser." [id :as {{:keys [description name parameters caveats points_of_interest show_in_getting_started enable_embedding embedding_params], :as dashboard} :body}] {name (s/maybe su/NonBlankString) - description (s/maybe su/NonBlankString) + description (s/maybe s/Str) caveats (s/maybe su/NonBlankString) points_of_interest (s/maybe su/NonBlankString) show_in_getting_started (s/maybe su/NonBlankString) diff --git a/src/metabase/db.clj b/src/metabase/db.clj index 75fcf7b19b7ff3c9325796c3ab3867bdff9c81a3..aede803e3c95cd1f911d4e38e187618be0d1f310 100644 --- a/src/metabase/db.clj +++ b/src/metabase/db.clj @@ -203,6 +203,23 @@ ^Database database (.findCorrectDatabaseImplementation (database-factory) liquibase-conn)] (Liquibase. changelog-file (ClassLoaderResourceAccessor.) database)))) +(defn consolidate-liquibase-changesets + "Consolidate all previous DB migrations so they came from single file. + Previous migrations where stored in many small files which added seconds + per file to the startup time because liquibase was checking the jar + signature for each file. This function is required to correct the liquibase + tables to reflect that these migrations where moved to a single file. + + see https://github.com/metabase/metabase/issues/3715" + [conn] + (let [fresh-install? (jdbc/with-db-metadata [meta (jdbc-details)] ;; don't migrate on fresh install + (empty? (jdbc/metadata-query (.getTables meta nil nil "DATABASECHANGELOG" (into-array String ["TABLE"]))))) + query (if (= (db-type) :h2) + "UPDATE DATABASECHANGELOG SET FILENAME = ?" + "UPDATE databasechangelog SET filename = ?")] + (when-not fresh-install? + (jdbc/execute! conn [query "migrations/000_migrations.yaml"])))) + (defn migrate! "Migrate the database (this can also be ran via command line like `java -jar metabase.jar migrate up` or `lein run migrate up`): @@ -229,6 +246,7 @@ (log/info "Setting up Liquibase...") (try (let [liquibase (conn->liquibase conn)] + (consolidate-liquibase-changesets conn) (log/info "Liquibase is ready.") (case direction :up (migrate-up-if-needed! conn liquibase) diff --git a/src/metabase/driver/bigquery.clj b/src/metabase/driver/bigquery.clj index e979b235e799f2c45ea0ab408e1f65d60c472353..6e9b011b647f2770f88ba82ed3b44dbb639201bb 100644 --- a/src/metabase/driver/bigquery.clj +++ b/src/metabase/driver/bigquery.clj @@ -77,7 +77,8 @@ (defn- can-connect? [details-map] {:pre [(map? details-map)]} - (boolean (describe-database {:details details-map}))) + ;; check whether we can connect by just fetching the first page of tables for the database. If that succeeds we're g2g + (boolean (list-tables {:details details-map}))) (defn- ^Table get-table @@ -358,13 +359,71 @@ ;; ORDER BY [sad_toucan_incidents.incidents.timestamp] ASC ;; LIMIT 10 -(defn- field->identitfier [field] +(defn- deduplicate-aliases + "Given a sequence of aliases, return a sequence where duplicate aliases have been appropriately suffixed. + + (deduplicate-aliases [\"sum\" \"count\" \"sum\" \"avg\" \"sum\" \"min\"]) + ;; -> [\"sum\" \"count\" \"sum_2\" \"avg\" \"sum_3\" \"min\"]" + [aliases] + (loop [acc [], alias->use-count {}, [alias & more, :as aliases] aliases] + (let [use-count (get alias->use-count alias)] + (cond + (empty? aliases) acc + (not alias) (recur (conj acc alias) alias->use-count more) + (not use-count) (recur (conj acc alias) (assoc alias->use-count alias 1) more) + :else (let [new-count (inc use-count) + new-alias (str alias "_" new-count)] + (recur (conj acc new-alias) (assoc alias->use-count alias new-count, new-alias 1) more)))))) + +(defn- select-subclauses->aliases + "Return a vector of aliases used in HoneySQL SELECT-SUBCLAUSES. + (For clauses that aren't aliased, `nil` is returned as a placeholder)." + [select-subclauses] + (for [subclause select-subclauses] + (when (and (vector? subclause) + (= 2 (count subclause))) + (second subclause)))) + +(defn update-select-subclause-aliases + "Given a vector of HoneySQL SELECT-SUBCLAUSES and a vector of equal length of NEW-ALIASES, + return a new vector with combining the original `SELECT` subclauses with the new aliases. + + Subclauses that are not aliased are not modified; they are given a placeholder of `nil` in the NEW-ALIASES vector. + + (update-select-subclause-aliases [[:user_id \"user_id\"] :venue_id] + [\"user_id_2\" nil]) + ;; -> [[:user_id \"user_id_2\"] :venue_id]" + [select-subclauses new-aliases] + (for [[subclause new-alias] (partition 2 (interleave select-subclauses new-aliases))] + (if-not new-alias + subclause + [(first subclause) new-alias]))) + +(defn- deduplicate-select-aliases + "Replace duplicate aliases in SELECT-SUBCLAUSES with appropriately suffixed aliases. + + BigQuery doesn't allow duplicate aliases in `SELECT` statements; a statement like `SELECT sum(x) AS sum, sum(y) AS sum` is invalid. (See #4089) + To work around this, we'll modify the HoneySQL aliases to make sure the same one isn't used twice by suffixing duplicates appropriately. + (We'll generate SQL like `SELECT sum(x) AS sum, sum(y) AS sum_2` instead.)" + [select-subclauses] + (let [aliases (select-subclauses->aliases select-subclauses) + deduped (deduplicate-aliases aliases)] + (update-select-subclause-aliases select-subclauses deduped))) + +(defn- apply-aggregation + "BigQuery's implementation of `apply-aggregation` just hands off to the normal Generic SQL implementation, but calls `deduplicate-select-aliases` on the results." + [driver honeysql-form query] + (-> (sqlqp/apply-aggregation driver honeysql-form query) + (update :select deduplicate-select-aliases))) + + +(defn- field->breakout-identifier [field] (hsql/raw (str \[ (field->alias field) \]))) (defn- apply-breakout [honeysql-form {breakout-fields :breakout, fields-fields :fields}] (-> honeysql-form ;; Group by all the breakout fields - ((partial apply h/group) (map field->identitfier breakout-fields)) + ((partial apply h/group) (map field->breakout-identifier breakout-fields)) ;; Add fields form only for fields that weren't specified in :fields clause -- we don't want to include it twice, or HoneySQL will barf ((partial apply h/merge-select) (for [field breakout-fields :when (not (contains? (set fields-fields) field))] @@ -372,9 +431,9 @@ (defn- apply-order-by [honeysql-form {subclauses :order-by}] (loop [honeysql-form honeysql-form, [{:keys [field direction]} & more] subclauses] - (let [honeysql-form (h/merge-order-by honeysql-form [(field->identitfier field) (case direction - :ascending :asc - :descending :desc)])] + (let [honeysql-form (h/merge-order-by honeysql-form [(field->breakout-identifier field) (case direction + :ascending :asc + :descending :desc)])] (if (seq more) (recur honeysql-form more) honeysql-form)))) @@ -398,7 +457,8 @@ (u/strict-extend BigQueryDriver sql/ISQLDriver (merge (sql/ISQLDriverDefaultsMixin) - {:apply-breakout (u/drop-first-arg apply-breakout) + {:apply-aggregation apply-aggregation + :apply-breakout (u/drop-first-arg apply-breakout) :apply-order-by (u/drop-first-arg apply-order-by) :column->base-type (constantly nil) ; these two are actually not applicable :connection-details->spec (constantly nil) ; since we don't use JDBC diff --git a/src/metabase/driver/crate.clj b/src/metabase/driver/crate.clj index 6d88591a90c6febca681fce0017ddc09e696d769..55082daf911962089bfc19d9a3e481c7ff75aa36 100644 --- a/src/metabase/driver/crate.clj +++ b/src/metabase/driver/crate.clj @@ -1,10 +1,12 @@ (ns metabase.driver.crate (:require [clojure.java.jdbc :as jdbc] + [clojure.tools.logging :as log] [honeysql.core :as hsql] [metabase.driver :as driver] [metabase.driver.crate.util :as crate-util] [metabase.driver.generic-sql :as sql] - [metabase.util :as u])) + [metabase.util :as u]) + (:import java.sql.DatabaseMetaData)) (def ^:private ^:const column->base-type "Map of Crate column types -> Field base types @@ -55,6 +57,39 @@ (defn- string-length-fn [field-key] (hsql/call :char_length field-key)) +(defn- describe-table-fields + [database, driver, {:keys [schema name]}] + (let [columns (jdbc/query + (sql/db->jdbc-connection-spec database) + [(format "select column_name, data_type as type_name + from information_schema.columns + where table_name like '%s' and table_schema like '%s' + and data_type != 'object_array'" name schema)])] ; clojure jdbc can't handle fields of type "object_array" atm + (set (for [{:keys [column_name type_name]} columns] + {:name column_name + :custom {:column-type type_name} + :base-type (or (column->base-type (keyword type_name)) + (do (log/warn (format "Don't know how to map column type '%s' to a Field base_type, falling back to :type/*." type_name)) + :type/*))})))) + +(defn- add-table-pks + [^DatabaseMetaData metadata, table] + (let [pks (->> (.getPrimaryKeys metadata nil nil (:name table)) + jdbc/result-set-seq + (mapv :column_name) + set)] + (update table :fields (fn [fields] + (set (for [field fields] + (if-not (contains? pks (:name field)) + field + (assoc field :pk? true)))))))) + +(defn- describe-table [driver database table] + (sql/with-metadata [metadata driver database] + (->> (describe-table-fields database driver table) + (assoc (select-keys table [:name :schema]) :fields) + ;; find PKs and mark them + (add-table-pks metadata)))) (defrecord CrateDriver [] clojure.lang.Named @@ -65,6 +100,7 @@ (merge (sql/IDriverSQLDefaultsMixin) {:can-connect? (u/drop-first-arg can-connect?) :date-interval crate-util/date-interval + :describe-table describe-table :details-fields (constantly [{:name "hosts" :display-name "Hosts" :default "localhost:5432"}]) @@ -75,6 +111,8 @@ :column->base-type (u/drop-first-arg column->base-type) :string-length-fn (u/drop-first-arg string-length-fn) :date crate-util/date + :quote-style (constantly :crate) + :field->alias (constantly nil) :unix-timestamp->timestamp crate-util/unix-timestamp->timestamp :current-datetime-fn (constantly now)})) diff --git a/src/metabase/models/dashboard.clj b/src/metabase/models/dashboard.clj index 2dedbb90f356e56bd0f8adcb87102d70b07c4b31..660819acfdaf2294b49759750e760996da2c48ec 100644 --- a/src/metabase/models/dashboard.clj +++ b/src/metabase/models/dashboard.clj @@ -88,23 +88,24 @@ :creator_id user-id) (events/publish-event! :dashboard-create))) + + (defn update-dashboard! "Update a `Dashboard`" - [{:keys [id name description parameters caveats points_of_interest show_in_getting_started enable_embedding embedding_params], :as dashboard} user-id] + [dashboard user-id] {:pre [(map? dashboard) - (integer? id) - (u/maybe? u/sequence-of-maps? parameters) + (u/maybe? u/sequence-of-maps? (:parameters dashboard)) (integer? user-id)]} - (db/update-non-nil-keys! Dashboard id - :description description - :name name - :parameters parameters - :caveats caveats - :points_of_interest points_of_interest - :enable_embedding enable_embedding - :embedding_params embedding_params - :show_in_getting_started show_in_getting_started) - (u/prog1 (Dashboard id) + (db/update! Dashboard (u/get-id dashboard) + (merge + ;; description is allowed to be `nil` + (when (contains? dashboard :description) + {:description (:description dashboard)}) + ;; only set everything else if its non-nil + (into {} (for [k [:name :parameters :caveats :points_of_interest :show_in_getting_started :enable_embedding :embedding_params] + :when (k dashboard)] + {k (k dashboard)})))) + (u/prog1 (Dashboard (u/get-id dashboard)) (events/publish-event! :dashboard-update (assoc <> :actor_id user-id)))) diff --git a/src/metabase/util/honeysql_extensions.clj b/src/metabase/util/honeysql_extensions.clj index 5b21d722754cf15f64f30df2d3a4e9a6e56e6331..70bfe6de28eaa0af1de1aae991c085fa5f54f685 100644 --- a/src/metabase/util/honeysql_extensions.clj +++ b/src/metabase/util/honeysql_extensions.clj @@ -21,6 +21,25 @@ (intern 'honeysql.format 'quote-fns (assoc quote-fns :h2 (comp s/upper-case ansi-quote-fn)))) + +;; `:crate` quote style that correctly quotes nested column identifiers +(defn- str-insert + "Insert C in string S at index I." + [s c i] + (str c (subs s 0 i) c (subs s i))) + +(defn- crate-column-identifier + [^CharSequence s] + (let [idx (s/index-of s "[")] + (if (nil? idx) + (str \" s \") + (str-insert s "\"" idx)))) + +(let [quote-fns @(resolve 'honeysql.format/quote-fns)] + (intern 'honeysql.format 'quote-fns + (assoc quote-fns :crate crate-column-identifier))) + + ;; register the `extract` function with HoneySQL ;; (hsql/format (hsql/call :extract :a :b)) -> "extract(a from b)" (defmethod hformat/fn-handler "extract" [_ unit expr] diff --git a/test/metabase/api/card_test.clj b/test/metabase/api/card_test.clj index 1a3bb3e25ce76b6cc7980a4b3f2899d09d88a7a5..a42630ea44f06bb291c5756a1f8802529f291577 100644 --- a/test/metabase/api/card_test.clj +++ b/test/metabase/api/card_test.clj @@ -247,6 +247,20 @@ (set-archived! true) (set-archived! false)]))) +;; Can we clear the description of a Card? (#4738) +(expect + nil + (with-temp-card [card {:description "What a nice Card"}] + ((user->client :rasta) :put 200 (str "card/" (u/get-id card)) {:description nil}) + (db/select-one-field :description Card :id (u/get-id card)))) + +;; description should be blankable as well +(expect + "" + (with-temp-card [card {:description "What a nice Card"}] + ((user->client :rasta) :put 200 (str "card/" (u/get-id card)) {:description ""}) + (db/select-one-field :description Card :id (u/get-id card)))) + ;; Can we update a card's embedding_params? (expect {:abc "enabled"} @@ -514,6 +528,22 @@ "Not found." ((user->client :rasta) :get 404 "card/" :collection :some_fake_collection_slug)) +;; Make sure GET /api/card?collection=<slug> still works with Collections with URL-encoded Slugs (#4535) +(expect + [] + (tt/with-temp Collection [collection {:name "Obsługa klienta"}] + (do + (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection) + ((user->client :rasta) :get 200 "card/" :collection "obs%C5%82uga_klienta")))) + +;; ...even if the slug isn't passed in URL-encoded +(expect + [] + (tt/with-temp Collection [collection {:name "Obsługa klienta"}] + (do + (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection) + ((user->client :rasta) :get 200 "card/" :collection "obsługa_klienta")))) + ;;; ------------------------------------------------------------ Bulk Collections Update (POST /api/card/collections) ------------------------------------------------------------ diff --git a/test/metabase/api/dashboard_test.clj b/test/metabase/api/dashboard_test.clj index 5ee7f99801c38c1b1de019ed090be47362e6cd41..3020f1edddba5fbd21ffe2a5a0ffcbe17e3a2bcb 100644 --- a/test/metabase/api/dashboard_test.clj +++ b/test/metabase/api/dashboard_test.clj @@ -159,6 +159,19 @@ :creator_id (user->id :trashbird)}) (Dashboard dashboard-id)]))) +;; Can we clear the description of a Dashboard? (#4738) +(expect + nil + (tt/with-temp Dashboard [dashboard {:description "What a nice Dashboard"}] + ((user->client :rasta) :put 200 (str "dashboard/" (u/get-id dashboard)) {:description nil}) + (db/select-one-field :description Dashboard :id (u/get-id dashboard)))) + +(expect + "" + (tt/with-temp Dashboard [dashboard {:description "What a nice Dashboard"}] + ((user->client :rasta) :put 200 (str "dashboard/" (u/get-id dashboard)) {:description ""}) + (db/select-one-field :description Dashboard :id (u/get-id dashboard)))) + ;; ## DELETE /api/dashboard/:id (expect diff --git a/test/metabase/driver/bigquery_test.clj b/test/metabase/driver/bigquery_test.clj index 97fd5c353f76e42e5f0d4f75ae0ece8080f29f40..976bf1d3410d88076d6b5c1b41f58b063ec2f709 100644 --- a/test/metabase/driver/bigquery_test.clj +++ b/test/metabase/driver/bigquery_test.clj @@ -1,11 +1,14 @@ (ns metabase.driver.bigquery-test - (:require metabase.driver.bigquery + (:require [expectations :refer :all] + metabase.driver.bigquery [metabase.models.database :as database] [metabase.query-processor :as qp] + [metabase.query-processor.expand :as ql] [metabase.query-processor-test :as qptest] [metabase.test.data :as data] (metabase.test.data [datasets :refer [expect-with-engine]] - [interface :refer [def-database-definition]]))) + [interface :refer [def-database-definition]]) + [metabase.test.util :as tu])) ;; Test native queries @@ -35,9 +38,53 @@ (expect-with-engine :bigquery {:rows [[113]] :columns ["User_ID_Plus_Venue_ID"]} - (qptest/rows+column-names (qp/process-query {:database (data/id) - :type "query" - :query {:source_table (data/id :checkins) - :aggregation [["named" ["max" ["+" ["field-id" (data/id :checkins :user_id)] - ["field-id" (data/id :checkins :venue_id)]]] - "User ID Plus Venue ID"]]}}))) + (qptest/rows+column-names + (qp/process-query {:database (data/id) + :type "query" + :query {:source_table (data/id :checkins) + :aggregation [["named" ["max" ["+" ["field-id" (data/id :checkins :user_id)] + ["field-id" (data/id :checkins :venue_id)]]] + "User ID Plus Venue ID"]]}}))) + +;; make sure BigQuery can handle two aggregations with the same name (#4089) +(tu/resolve-private-vars metabase.driver.bigquery + deduplicate-aliases update-select-subclause-aliases) + +(expect + ["sum" "count" "sum_2" "avg" "sum_3" "min"] + (deduplicate-aliases ["sum" "count" "sum" "avg" "sum" "min"])) + +(expect + ["sum" "count" "sum_2" "avg" "sum_2_2" "min"] + (deduplicate-aliases ["sum" "count" "sum" "avg" "sum_2" "min"])) + +(expect + ["sum" "count" nil "sum_2"] + (deduplicate-aliases ["sum" "count" nil "sum"])) + +(expect + [[:user_id "user_id_2"] :venue_id] + (update-select-subclause-aliases [[:user_id "user_id"] :venue_id] + ["user_id_2" nil])) + + +(expect-with-engine :bigquery + {:rows [[7929 7929]], :columns ["sum" "sum_2"]} + (qptest/rows+column-names + (qp/process-query {:database (data/id) + :type "query" + :query (-> {} + (ql/source-table (data/id :checkins)) + (ql/aggregation (ql/sum (ql/field-id (data/id :checkins :user_id))) + (ql/sum (ql/field-id (data/id :checkins :user_id)))))}))) + +(expect-with-engine :bigquery + {:rows [[7929 7929 7929]], :columns ["sum" "sum_2" "sum_3"]} + (qptest/rows+column-names + (qp/process-query {:database (data/id) + :type "query" + :query (-> {} + (ql/source-table (data/id :checkins)) + (ql/aggregation (ql/sum (ql/field-id (data/id :checkins :user_id))) + (ql/sum (ql/field-id (data/id :checkins :user_id))) + (ql/sum (ql/field-id (data/id :checkins :user_id)))))}))) diff --git a/test/metabase/permissions_collection_test.clj b/test/metabase/permissions_collection_test.clj index 575f572aff5b0f7cc72f275214c2455874c91293..d6e82ec37120919812faf7c81eb07854a1964be5 100644 --- a/test/metabase/permissions_collection_test.clj +++ b/test/metabase/permissions_collection_test.clj @@ -55,7 +55,9 @@ (println "[In the occasionally failing test]") ; DEBUG (set-card-collection! collection) (permissions/grant-collection-read-permissions! (group/all-users) collection) - (can-run-query? :rasta))) + ;; try it twice because sometimes it randomly fails :unamused: + (or (can-run-query? :rasta) + (can-run-query? :rasta)))) ;; Make sure a User isn't allowed to save a Card they have collections readwrite permissions for ;; if they don't have data perms for the query diff --git a/yarn.lock b/yarn.lock index 43f9be44d4c1e33334761bbb467b0bd1d56ff30f..75d73d82730fd2d4d05f74465724aff3d3f30292 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,103 +2,6 @@ # yarn lockfile v1 -"@kadira/react-split-pane@^1.4.0": - version "1.4.7" - resolved "https://registry.yarnpkg.com/@kadira/react-split-pane/-/react-split-pane-1.4.7.tgz#6d753d4a9fe62fe82056e323a6bcef7f026972b5" - -"@kadira/storybook-addon-actions@^1.0.2": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@kadira/storybook-addon-actions/-/storybook-addon-actions-1.1.1.tgz#5053485583fadea413710d6405454dc168a7efc7" - dependencies: - deep-equal "^1.0.1" - json-stringify-safe "^5.0.1" - react-inspector "^1.1.0" - -"@kadira/storybook-addon-links@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@kadira/storybook-addon-links/-/storybook-addon-links-1.0.1.tgz#566136a8020b60f82f146ef37d93b0c86de969d8" - -"@kadira/storybook-addons@^1.5.0": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@kadira/storybook-addons/-/storybook-addons-1.6.1.tgz#e84923d298b38c7c1231ddebc219dfb87b2858a6" - -"@kadira/storybook-channel-postmsg@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@kadira/storybook-channel-postmsg/-/storybook-channel-postmsg-2.0.1.tgz#2a9065bf0647c940b8f9a3a7342a3e12e321af72" - dependencies: - "@kadira/storybook-channel" "^1.1.0" - json-stringify-safe "^5.0.1" - -"@kadira/storybook-channel@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@kadira/storybook-channel/-/storybook-channel-1.1.0.tgz#806d1cdf2498d11cce09871a6fd27bbb41ed3564" - -"@kadira/storybook-ui@^3.10.1": - version "3.11.0" - resolved "https://registry.yarnpkg.com/@kadira/storybook-ui/-/storybook-ui-3.11.0.tgz#a5ccdcc479aa5e08465c58e7df493e37e4b2a14a" - dependencies: - "@kadira/react-split-pane" "^1.4.0" - babel-runtime "^6.5.0" - deep-equal "^1.0.1" - events "^1.1.1" - fuzzysearch "^1.0.3" - json-stringify-safe "^5.0.1" - keycode "^2.1.1" - lodash.pick "^4.2.1" - lodash.sortby "^4.7.0" - mantra-core "^1.7.0" - podda "^1.2.1" - qs "^6.2.0" - react-fuzzy "^0.3.3" - react-inspector "^1.1.0" - react-komposer "^2.0.0" - react-modal "^1.2.1" - redux "^3.5.2" - -"@kadira/storybook@^2.35.2": - version "2.35.3" - resolved "https://registry.yarnpkg.com/@kadira/storybook/-/storybook-2.35.3.tgz#8106195e1733623baf60db6adaa678dc29285d12" - dependencies: - "@kadira/react-split-pane" "^1.4.0" - "@kadira/storybook-addon-actions" "^1.0.2" - "@kadira/storybook-addon-links" "^1.0.0" - "@kadira/storybook-addons" "^1.5.0" - "@kadira/storybook-channel-postmsg" "^2.0.1" - "@kadira/storybook-ui" "^3.10.1" - airbnb-js-shims "^1.0.1" - autoprefixer "^6.3.7" - babel-core "^6.11.4" - babel-loader "^6.2.4" - babel-plugin-react-docgen "^1.4.2" - babel-preset-react-app "^1.0.0" - babel-runtime "^6.9.2" - case-sensitive-paths-webpack-plugin "^1.1.2" - chalk "^1.1.3" - commander "^2.9.0" - common-tags "^1.3.1" - configstore "^2.0.0" - css-loader "^0.26.1" - express "^4.13.3" - file-loader "^0.9.0" - find-cache-dir "^0.1.1" - json-loader "^0.5.4" - json-stringify-safe "^5.0.1" - json5 "^0.5.0" - lodash.pick "^4.2.0" - postcss-loader "1.1.0" - qs "^6.1.0" - react-modal "^1.2.0" - redux "^3.5.2" - request "^2.74.0" - serve-favicon "^2.3.0" - shelljs "^0.7.4" - style-loader "0.13.1" - url-loader "^0.5.7" - uuid "^2.0.3" - webpack "^1.13.1" - webpack-dev-middleware "^1.6.0" - webpack-hot-middleware "^2.13.2" - "@slack/client@^3.5.4": version "3.8.1" resolved "https://registry.yarnpkg.com/@slack/client/-/client-3.8.1.tgz#ac1744f3e87ebd52f60979ecc084c615544caeeb" @@ -174,19 +77,6 @@ agent-base@2: extend "~3.0.0" semver "~5.0.1" -airbnb-js-shims@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-1.1.1.tgz#27224f0030f244e6570442ed1020772c1434aec2" - dependencies: - array-includes "^3.0.2" - es5-shim "^4.5.9" - es6-shim "^0.35.1" - object.entries "^1.0.3" - object.getownpropertydescriptors "^2.0.3" - object.values "^1.0.3" - string.prototype.padend "^3.0.0" - string.prototype.padstart "^3.0.0" - ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" @@ -322,13 +212,6 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" -array-includes@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.2.tgz#7c867b4d1235c2b5687c874f3344bff4e002beba" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.0" - array-parallel@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/array-parallel/-/array-parallel-0.1.3.tgz#8f785308926ed5aa478c47e64d1b334b6c0c947d" @@ -408,10 +291,6 @@ ast-types@0.9.4: version "0.9.4" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.4.tgz#410d1f81890aeb8e0a38621558ba5869ae53c91b" -ast-types@0.9.5: - version "0.9.5" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.5.tgz#1a660a09945dbceb1f9c9cbb715002617424e04a" - async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -442,7 +321,7 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -autoprefixer@^6.0.2, autoprefixer@^6.3.1, autoprefixer@^6.3.7: +autoprefixer@^6.0.2, autoprefixer@^6.3.1: version "6.7.5" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.5.tgz#50848f39dc08730091d9495023487e7cc21f518d" dependencies: @@ -490,7 +369,7 @@ babel-code-frame@6.22.0, babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, bab esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@^6.0.0, babel-core@^6.11.4, babel-core@^6.20.0, babel-core@^6.23.0: +babel-core@^6.0.0, babel-core@^6.20.0, babel-core@^6.23.0: version "6.23.1" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.23.1.tgz#c143cb621bb2f621710c220c5d579d15b8a442df" dependencies: @@ -562,7 +441,7 @@ babel-helper-builder-react-jsx@^6.23.0: esutils "^2.0.0" lodash "^4.2.0" -babel-helper-call-delegate@^6.22.0, babel-helper-call-delegate@^6.8.0: +babel-helper-call-delegate@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz#119921b56120f17e9dae3f74b4f5cc7bcc1b37ef" dependencies: @@ -597,7 +476,7 @@ babel-helper-explode-class@^6.22.0: babel-traverse "^6.22.0" babel-types "^6.22.0" -babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0, babel-helper-function-name@^6.8.0: +babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz#25742d67175c8903dbe4b6cb9d9e1fcb8dcf23a6" dependencies: @@ -607,7 +486,7 @@ babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0, babel-he babel-traverse "^6.23.0" babel-types "^6.23.0" -babel-helper-get-function-arity@^6.22.0, babel-helper-get-function-arity@^6.8.0: +babel-helper-get-function-arity@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz#0beb464ad69dc7347410ac6ade9f03a50634f5ce" dependencies: @@ -691,7 +570,7 @@ babel-plugin-add-react-displayname@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.4.tgz#bc2a74bcbee6e505025b3352fea85ee7bc4c6f7c" -babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants@^6.3.13: +babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" dependencies: @@ -710,14 +589,6 @@ babel-plugin-jest-hoist@^18.0.0: version "18.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-18.0.0.tgz#4150e70ecab560e6e7344adc849498072d34e12a" -babel-plugin-react-docgen@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-1.4.2.tgz#04c02133b84b6cc182d35de2162f15764da03e7c" - dependencies: - babel-types "^6.16.0" - lodash "4.x.x" - react-docgen "^2.12.1" - babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" @@ -754,7 +625,7 @@ babel-plugin-syntax-export-extensions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" -babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.3.13: +babel-plugin-syntax-flow@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" @@ -770,7 +641,7 @@ babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" -babel-plugin-syntax-trailing-function-commas@^6.13.0, babel-plugin-syntax-trailing-function-commas@^6.22.0: +babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" @@ -782,7 +653,7 @@ babel-plugin-transform-async-generator-functions@^6.22.0: babel-plugin-syntax-async-generators "^6.5.0" babel-runtime "^6.22.0" -babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.8.0: +babel-plugin-transform-async-to-generator@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz#194b6938ec195ad36efc4c33a971acf00d8cd35e" dependencies: @@ -805,14 +676,6 @@ babel-plugin-transform-class-constructor-call@^6.22.0: babel-runtime "^6.22.0" babel-template "^6.22.0" -babel-plugin-transform-class-properties@6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.16.0.tgz#969bca24d34e401d214f36b8af5c1346859bc904" - dependencies: - babel-helper-function-name "^6.8.0" - babel-plugin-syntax-class-properties "^6.8.0" - babel-runtime "^6.9.1" - babel-plugin-transform-class-properties@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.23.0.tgz#187b747ee404399013563c993db038f34754ac3b" @@ -847,19 +710,19 @@ babel-plugin-transform-do-expressions@^6.22.0: babel-plugin-syntax-do-expressions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-es2015-arrow-functions@^6.22.0, babel-plugin-transform-es2015-arrow-functions@^6.3.13: +babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0, babel-plugin-transform-es2015-block-scoped-functions@^6.3.13: +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoping@^6.22.0, babel-plugin-transform-es2015-block-scoping@^6.6.0: +babel-plugin-transform-es2015-block-scoping@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz#e48895cf0b375be148cd7c8879b422707a053b51" dependencies: @@ -869,7 +732,7 @@ babel-plugin-transform-es2015-block-scoping@^6.22.0, babel-plugin-transform-es20 babel-types "^6.23.0" lodash "^4.2.0" -babel-plugin-transform-es2015-classes@^6.22.0, babel-plugin-transform-es2015-classes@^6.6.0: +babel-plugin-transform-es2015-classes@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz#49b53f326202a2fd1b3bbaa5e2edd8a4f78643c1" dependencies: @@ -883,39 +746,33 @@ babel-plugin-transform-es2015-classes@^6.22.0, babel-plugin-transform-es2015-cla babel-traverse "^6.23.0" babel-types "^6.23.0" -babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.3.13: +babel-plugin-transform-es2015-computed-properties@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.22.0.tgz#7c383e9629bba4820c11b0425bdd6290f7f057e7" dependencies: babel-runtime "^6.22.0" babel-template "^6.22.0" -babel-plugin-transform-es2015-destructuring@6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.16.0.tgz#050fe0866f5d53b36062ee10cdf5bfe64f929627" - dependencies: - babel-runtime "^6.9.0" - -babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.6.0: +babel-plugin-transform-es2015-destructuring@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2015-duplicate-keys@^6.6.0: +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.22.0.tgz#672397031c21610d72dd2bbb0ba9fb6277e1c36b" dependencies: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.6.0: +babel-plugin-transform-es2015-for-of@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.3.13: +babel-plugin-transform-es2015-function-name@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz#f5fcc8b09093f9a23c76ac3d9e392c3ec4b77104" dependencies: @@ -923,13 +780,13 @@ babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es20 babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-literals@^6.22.0, babel-plugin-transform-es2015-literals@^6.3.13: +babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.8.0: +babel-plugin-transform-es2015-modules-amd@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.22.0.tgz#bf69cd34889a41c33d90dfb740e0091ccff52f21" dependencies: @@ -937,7 +794,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.22.0" -babel-plugin-transform-es2015-modules-commonjs@^6.22.0, babel-plugin-transform-es2015-modules-commonjs@^6.6.0: +babel-plugin-transform-es2015-modules-commonjs@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.23.0.tgz#cba7aa6379fb7ec99250e6d46de2973aaffa7b92" dependencies: @@ -946,7 +803,7 @@ babel-plugin-transform-es2015-modules-commonjs@^6.22.0, babel-plugin-transform-e babel-template "^6.23.0" babel-types "^6.23.0" -babel-plugin-transform-es2015-modules-systemjs@^6.12.0, babel-plugin-transform-es2015-modules-systemjs@^6.22.0: +babel-plugin-transform-es2015-modules-systemjs@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz#ae3469227ffac39b0310d90fec73bfdc4f6317b0" dependencies: @@ -954,7 +811,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.12.0, babel-plugin-transform-e babel-runtime "^6.22.0" babel-template "^6.23.0" -babel-plugin-transform-es2015-modules-umd@^6.12.0, babel-plugin-transform-es2015-modules-umd@^6.22.0: +babel-plugin-transform-es2015-modules-umd@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.23.0.tgz#8d284ae2e19ed8fe21d2b1b26d6e7e0fcd94f0f1" dependencies: @@ -962,25 +819,14 @@ babel-plugin-transform-es2015-modules-umd@^6.12.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.23.0" -babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.3.13: +babel-plugin-transform-es2015-object-super@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.22.0.tgz#daa60e114a042ea769dd53fe528fc82311eb98fc" dependencies: babel-helper-replace-supers "^6.22.0" babel-runtime "^6.22.0" -babel-plugin-transform-es2015-parameters@6.17.0: - version "6.17.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.17.0.tgz#e06d30cef897f46adb4734707bbe128a0d427d58" - dependencies: - babel-helper-call-delegate "^6.8.0" - babel-helper-get-function-arity "^6.8.0" - babel-runtime "^6.9.0" - babel-template "^6.16.0" - babel-traverse "^6.16.0" - babel-types "^6.16.0" - -babel-plugin-transform-es2015-parameters@^6.22.0, babel-plugin-transform-es2015-parameters@^6.6.0: +babel-plugin-transform-es2015-parameters@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz#3a2aabb70c8af945d5ce386f1a4250625a83ae3b" dependencies: @@ -991,20 +837,20 @@ babel-plugin-transform-es2015-parameters@^6.22.0, babel-plugin-transform-es2015- babel-traverse "^6.23.0" babel-types "^6.23.0" -babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.3.13: +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.22.0.tgz#8ba776e0affaa60bff21e921403b8a652a2ff723" dependencies: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.3.13: +babel-plugin-transform-es2015-spread@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.3.13: +babel-plugin-transform-es2015-sticky-regex@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz#ab316829e866ee3f4b9eb96939757d19a5bc4593" dependencies: @@ -1012,19 +858,19 @@ babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es201 babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-template-literals@^6.22.0, babel-plugin-transform-es2015-template-literals@^6.6.0: +babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.6.0: +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es2015-unicode-regex@^6.3.13: +babel-plugin-transform-es2015-unicode-regex@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz#8d9cc27e7ee1decfe65454fb986452a04a613d20" dependencies: @@ -1032,7 +878,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es20 babel-runtime "^6.22.0" regexpu-core "^2.0.0" -babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.8.0: +babel-plugin-transform-exponentiation-operator@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.22.0.tgz#d57c8335281918e54ef053118ce6eb108468084d" dependencies: @@ -1047,7 +893,7 @@ babel-plugin-transform-export-extensions@^6.22.0: babel-plugin-syntax-export-extensions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.3.13, babel-plugin-transform-flow-strip-types@^6.8.0: +babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" dependencies: @@ -1061,13 +907,6 @@ babel-plugin-transform-function-bind@^6.22.0: babel-plugin-syntax-function-bind "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-object-rest-spread@6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.16.0.tgz#db441d56fffc1999052fdebe2e2f25ebd28e36a9" - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.0.0" - babel-plugin-transform-object-rest-spread@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" @@ -1075,47 +914,27 @@ babel-plugin-transform-object-rest-spread@^6.22.0: babel-plugin-syntax-object-rest-spread "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-react-constant-elements@6.9.1: - version "6.9.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-constant-elements/-/babel-plugin-transform-react-constant-elements-6.9.1.tgz#125b86d96cb322e2139b607fd749ad5fbb17f005" - dependencies: - babel-runtime "^6.9.1" - -babel-plugin-transform-react-display-name@^6.23.0, babel-plugin-transform-react-display-name@^6.3.13: +babel-plugin-transform-react-display-name@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.23.0.tgz#4398910c358441dc4cef18787264d0412ed36b37" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-react-jsx-self@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.11.0.tgz#605c9450c1429f97a930f7e1dfe3f0d9d0dbd0f4" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.9.0" - -babel-plugin-transform-react-jsx-self@^6.11.0, babel-plugin-transform-react-jsx-self@^6.22.0: +babel-plugin-transform-react-jsx-self@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" dependencies: babel-plugin-syntax-jsx "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-react-jsx-source@6.9.0: - version "6.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.9.0.tgz#af684a05c2067a86e0957d4f343295ccf5dccf00" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.9.0" - -babel-plugin-transform-react-jsx-source@^6.22.0, babel-plugin-transform-react-jsx-source@^6.3.13: +babel-plugin-transform-react-jsx-source@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" dependencies: babel-plugin-syntax-jsx "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-react-jsx@^6.23.0, babel-plugin-transform-react-jsx@^6.3.13: +babel-plugin-transform-react-jsx@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.23.0.tgz#23e892f7f2e759678eb5e4446a8f8e94e81b3470" dependencies: @@ -1123,26 +942,12 @@ babel-plugin-transform-react-jsx@^6.23.0, babel-plugin-transform-react-jsx@^6.3. babel-plugin-syntax-jsx "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-regenerator@6.16.1: - version "6.16.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.16.1.tgz#a75de6b048a14154aae14b0122756c5bed392f59" - dependencies: - babel-runtime "^6.9.0" - babel-types "^6.16.0" - private "~0.1.5" - -babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.6.0: +babel-plugin-transform-regenerator@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz#65740593a319c44522157538d690b84094617ea6" dependencies: regenerator-transform "0.9.8" -babel-plugin-transform-runtime@6.15.0: - version "6.15.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.15.0.tgz#3d75b4d949ad81af157570273846fb59aeb0d57c" - dependencies: - babel-runtime "^6.9.0" - babel-plugin-transform-strict-mode@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz#e008df01340fdc87e959da65991b7e05970c8c7c" @@ -1158,40 +963,7 @@ babel-polyfill@^6.23.0, babel-polyfill@^6.6.1: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-env@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-0.0.6.tgz#cda63a020069098fad12272a7a447a7c5bafb3c8" - dependencies: - babel-plugin-check-es2015-constants "^6.3.13" - babel-plugin-syntax-trailing-function-commas "^6.13.0" - babel-plugin-transform-async-to-generator "^6.8.0" - babel-plugin-transform-es2015-arrow-functions "^6.3.13" - babel-plugin-transform-es2015-block-scoped-functions "^6.3.13" - babel-plugin-transform-es2015-block-scoping "^6.6.0" - babel-plugin-transform-es2015-classes "^6.6.0" - babel-plugin-transform-es2015-computed-properties "^6.3.13" - babel-plugin-transform-es2015-destructuring "^6.6.0" - babel-plugin-transform-es2015-duplicate-keys "^6.6.0" - babel-plugin-transform-es2015-for-of "^6.6.0" - babel-plugin-transform-es2015-function-name "^6.3.13" - babel-plugin-transform-es2015-literals "^6.3.13" - babel-plugin-transform-es2015-modules-amd "^6.8.0" - babel-plugin-transform-es2015-modules-commonjs "^6.6.0" - babel-plugin-transform-es2015-modules-systemjs "^6.12.0" - babel-plugin-transform-es2015-modules-umd "^6.12.0" - babel-plugin-transform-es2015-object-super "^6.3.13" - babel-plugin-transform-es2015-parameters "^6.6.0" - babel-plugin-transform-es2015-shorthand-properties "^6.3.13" - babel-plugin-transform-es2015-spread "^6.3.13" - babel-plugin-transform-es2015-sticky-regex "^6.3.13" - babel-plugin-transform-es2015-template-literals "^6.6.0" - babel-plugin-transform-es2015-typeof-symbol "^6.6.0" - babel-plugin-transform-es2015-unicode-regex "^6.3.13" - babel-plugin-transform-exponentiation-operator "^6.8.0" - babel-plugin-transform-regenerator "^6.6.0" - browserslist "^1.4.0" - -babel-preset-es2015@^6.16.0, babel-preset-es2015@^6.6.0: +babel-preset-es2015@^6.6.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.22.0.tgz#af5a98ecb35eb8af764ad8a5a05eb36dc4386835" dependencies: @@ -1220,19 +992,6 @@ babel-preset-es2015@^6.16.0, babel-preset-es2015@^6.6.0: babel-plugin-transform-es2015-unicode-regex "^6.22.0" babel-plugin-transform-regenerator "^6.22.0" -babel-preset-es2016@^6.16.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-preset-es2016/-/babel-preset-es2016-6.22.0.tgz#b061aaa3983d40c9fbacfa3743b5df37f336156c" - dependencies: - babel-plugin-transform-exponentiation-operator "^6.22.0" - -babel-preset-es2017@^6.16.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-preset-es2017/-/babel-preset-es2017-6.22.0.tgz#de2f9da5a30c50d293fb54a0ba15d6ddc573f0f2" - dependencies: - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-preset-flow@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" @@ -1245,44 +1004,6 @@ babel-preset-jest@^18.0.0: dependencies: babel-plugin-jest-hoist "^18.0.0" -babel-preset-latest@6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-preset-latest/-/babel-preset-latest-6.16.0.tgz#5b87e19e250bb1213f13af4ec9dc7a51d53f388d" - dependencies: - babel-preset-es2015 "^6.16.0" - babel-preset-es2016 "^6.16.0" - babel-preset-es2017 "^6.16.0" - -babel-preset-react-app@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-1.0.0.tgz#e7613500859d96f177ba7a38a3ed0a923ee50da8" - dependencies: - babel-plugin-transform-class-properties "6.16.0" - babel-plugin-transform-es2015-destructuring "6.16.0" - babel-plugin-transform-es2015-parameters "6.17.0" - babel-plugin-transform-object-rest-spread "6.16.0" - babel-plugin-transform-react-constant-elements "6.9.1" - babel-plugin-transform-react-jsx-self "6.11.0" - babel-plugin-transform-react-jsx-source "6.9.0" - babel-plugin-transform-regenerator "6.16.1" - babel-plugin-transform-runtime "6.15.0" - babel-preset-env "0.0.6" - babel-preset-latest "6.16.0" - babel-preset-react "6.16.0" - babel-runtime "6.11.6" - -babel-preset-react@6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.16.0.tgz#aa117d60de0928607e343c4828906e4661824316" - dependencies: - babel-plugin-syntax-flow "^6.3.13" - babel-plugin-syntax-jsx "^6.3.13" - babel-plugin-transform-flow-strip-types "^6.3.13" - babel-plugin-transform-react-display-name "^6.3.13" - babel-plugin-transform-react-jsx "^6.3.13" - babel-plugin-transform-react-jsx-self "^6.11.0" - babel-plugin-transform-react-jsx-source "^6.3.13" - babel-preset-react@^6.5.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.23.0.tgz#eb7cee4de98a3f94502c28565332da9819455195" @@ -1341,14 +1062,7 @@ babel-register@^6.11.6, babel-register@^6.23.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@6.11.6: - version "6.11.6" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.11.6.tgz#6db707fef2d49c49bfa3cb64efdb436b518b8222" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.9.5" - -babel-runtime@6.x.x, babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.5.0, babel-runtime@^6.9.0, babel-runtime@^6.9.1, babel-runtime@^6.9.2: +babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" dependencies: @@ -1365,7 +1079,7 @@ babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0, babel-te babylon "^6.11.0" lodash "^4.2.0" -babel-traverse@^6.15.0, babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: +babel-traverse@^6.15.0, babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: version "6.23.1" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48" dependencies: @@ -1379,7 +1093,7 @@ babel-traverse@^6.15.0, babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-tr invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.15.0, babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: +babel-types@^6.15.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf" dependencies: @@ -1392,10 +1106,6 @@ babylon@6.15.0, babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: version "6.15.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e" -babylon@~5.8.3: - version "5.8.38" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd" - backo2@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -1591,7 +1301,7 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^1.0.0, browserslist@^1.0.1, browserslist@^1.4.0, browserslist@^1.5.2, browserslist@^1.7.5: +browserslist@^1.0.0, browserslist@^1.0.1, browserslist@^1.5.2, browserslist@^1.7.5: version "1.7.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.5.tgz#eca4713897b51e444283241facf3985de49a9e2b" dependencies: @@ -1701,10 +1411,6 @@ cardinal@^1.0.0: ansicolors "~0.2.1" redeyed "~1.0.0" -case-sensitive-paths-webpack-plugin@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-1.1.4.tgz#8aaedd5699a86cac2b34cf40d9b4145758978472" - caseless@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" @@ -1887,6 +1593,10 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" +collapse-white-space@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.2.tgz#9c463fb9c6d190d2dcae21a356a01bcae9eeef6d" + color-convert@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd" @@ -1974,12 +1684,6 @@ commander@2.9.x, commander@^2.8.1, commander@^2.9.0, commander@~2.9.0: dependencies: graceful-readlink ">= 1.0.0" -common-tags@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0" - dependencies: - babel-runtime "^6.18.0" - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2042,20 +1746,6 @@ concurrently@^3.1.0: supports-color "^3.2.3" tree-kill "^1.1.0" -configstore@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" - dependencies: - dot-prop "^3.0.0" - graceful-fs "^4.1.2" - mkdirp "^0.5.0" - object-assign "^4.0.1" - os-tmpdir "^1.0.0" - osenv "^0.1.0" - uuid "^2.0.1" - write-file-atomic "^1.1.2" - xdg-basedir "^2.0.0" - connect-history-api-fallback@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz#e51d17f8f0ef0db90a64fdb47de3051556e9f169" @@ -2529,13 +2219,6 @@ doctrine@1.5.0, doctrine@^1.2.2: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - dom-converter@~0.1: version "0.1.4" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.1.4.tgz#a45ef5727b890c9bffe6d7c876e7b19cb0e17f3b" @@ -2599,12 +2282,6 @@ domutils@1.5.1, domutils@^1.5.1: dom-serializer "0" domelementtype "1" -dot-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" - dependencies: - is-obj "^1.0.0" - ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -2618,6 +2295,10 @@ ecdsa-sig-formatter@1.0.9: base64url "^2.0.0" safe-buffer "^5.0.1" +editions@^1.1.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.3.tgz#0907101bdda20fac3cbe334c27cbd0688dc99a5b" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -2630,10 +2311,6 @@ elegant-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" -element-class@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/element-class/-/element-class-0.2.2.tgz#9d3bbd0767f9013ef8e1c8ebe722c1402a60050e" - elliptic@^6.0.0: version "6.3.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" @@ -2742,7 +2419,7 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0: +es-abstract@^1.6.1, es-abstract@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" dependencies: @@ -2766,10 +2443,6 @@ es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0. es6-iterator "2" es6-symbol "~3.1" -es5-shim@^4.5.9: - version "4.5.9" - resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.5.9.tgz#2a1e2b9e583ff5fed0c20a3ee2cbf3f75230a5c0" - es6-iterator@2: version "2.0.0" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" @@ -2811,10 +2484,6 @@ es6-set@~0.1.3: es6-symbol "3" event-emitter "~0.3.4" -es6-shim@^0.35.1: - version "0.35.3" - resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.3.tgz#9bfb7363feffff87a6cdb6cd93e405ec3c4b6f26" - es6-symbol@3, es6-symbol@~3.1, es6-symbol@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" @@ -3000,7 +2669,7 @@ esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" -esprima@^3.1.1, esprima@~3.1.0: +esprima@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -3035,10 +2704,6 @@ etag@~1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" -etag@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051" - event-emitter@~0.3.4: version "0.3.4" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" @@ -3050,7 +2715,7 @@ eventemitter3@1.x.x, eventemitter3@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" -events@^1.0.0, events@^1.1.1: +events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -3084,10 +2749,6 @@ execa@^0.6.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -exenv@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.0.tgz#3835f127abf075bfe082d0aed4484057c78e3c89" - exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" @@ -3296,10 +2957,6 @@ find-cache-dir@^0.1.1: mkdirp "^0.5.1" pkg-dir "^1.0.0" -find-parent-dir@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" - find-root@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/find-root/-/find-root-0.1.2.tgz#98d2267cff1916ccaf2743b3a0eea81d79d7dcd1" @@ -3376,10 +3033,6 @@ fresh@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" -fresh@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.4.0.tgz#475626a934a8d3480b2101a1d6ecef7dafd7c553" - fs-access@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" @@ -3456,14 +3109,6 @@ function.prototype.name@^1.0.0: function-bind "^1.1.0" is-callable "^1.1.2" -fuse.js@^2.2.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-2.6.1.tgz#d118e00f9a859f7b354ed4f7740214249e32a57a" - -fuzzysearch@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fuzzysearch/-/fuzzysearch-1.0.3.tgz#dffc80f6d6b04223f2226aa79dd194231096d008" - gauge@~2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09" @@ -3495,6 +3140,10 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" +get-own-enumerable-property-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-1.0.1.tgz#f1d4e3ad1402e039898e56d1e9b9aa924c26e484" + get-stdin@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" @@ -3564,7 +3213,7 @@ gm@~1.21.1: array-series "~0.1.5" debug "~2.2.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -3671,7 +3320,7 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" -hoist-non-react-statics@1.2.0, hoist-non-react-statics@1.x.x, hoist-non-react-statics@^1.0.0, hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.0.5, hoist-non-react-statics@^1.2.0: +hoist-non-react-statics@1.2.0, hoist-non-react-statics@^1.0.0, hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.0.5, hoist-non-react-statics@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" @@ -3798,15 +3447,6 @@ humanize-plus@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030" -husky@^0.13.2: - version "0.13.2" - resolved "https://registry.yarnpkg.com/husky/-/husky-0.13.2.tgz#9dcf212f88e61dba36f17be1a202ed61ff6c0661" - dependencies: - chalk "^1.1.3" - find-parent-dir "^0.3.0" - is-ci "^1.0.9" - normalize-path "^1.0.0" - icepick@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/icepick/-/icepick-1.3.0.tgz#e4942842ed8f9ee778d7dd78f7e36627f49fdaef" @@ -3852,10 +3492,6 @@ img-stats@^0.5.2: dependencies: xmldom "^0.1.19" -immutable@^3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2" - imports-loader@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-0.7.0.tgz#468c04de8075941cfab28146c755c24cc1f36ccd" @@ -3938,7 +3574,7 @@ interpret@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" -invariant@2.x.x, invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1: +invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" dependencies: @@ -4001,10 +3637,6 @@ is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" -is-dom@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.0.9.tgz#483832d52972073de12b9fe3f60320870da8370d" - is-dotfile@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" @@ -4074,7 +3706,7 @@ is-number@^2.0.2, is-number@^2.1.0: dependencies: kind-of "^3.0.2" -is-obj@^1.0.0: +is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -4098,6 +3730,12 @@ is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" +is-plain-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.1.tgz#4d7ca539bc9db9b737b8acb612f2318ef92f294f" + dependencies: + isobject "^1.0.0" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -4120,6 +3758,10 @@ is-regex@^1.0.3: dependencies: has "^1.0.1" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + is-relative@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" @@ -4196,6 +3838,10 @@ isnumeric@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/isnumeric/-/isnumeric-0.2.0.tgz#a2347ba360de19e33d0ffd590fddf7755cbf2e64" +isobject@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-1.0.2.tgz#f0f9b8ce92dd540fa0740882e3835a2e022ec78a" + isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -4603,7 +4249,7 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -4740,10 +4386,6 @@ karma@^1.3.0: tmp "0.0.31" useragent "^2.1.12" -keycode@^2.1.1: - version "2.1.8" - resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.8.tgz#94d2b7098215eff0e8f9a8931d5a59076c4532fb" - kind-of@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" @@ -4997,7 +4639,7 @@ lodash.isplainobject@^3.2.0: lodash.isarguments "^3.0.0" lodash.keysin "^3.0.0" -lodash.keys@^3.0.0, lodash.keys@^3.1.2: +lodash.keys@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" dependencies: @@ -5028,7 +4670,7 @@ lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" -lodash.pick@^4.2.0, lodash.pick@^4.2.1, lodash.pick@^4.4.0: +lodash.pick@^4.2.1: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" @@ -5048,10 +4690,6 @@ lodash.some@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - lodash.template@^4.2.4: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" @@ -5069,14 +4707,14 @@ lodash.uniq@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@4.x.x, lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.6, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.5.1: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - lodash@^3.7.0, lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" +lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.6, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.5.1: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -5142,14 +4780,6 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -mantra-core@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/mantra-core/-/mantra-core-1.7.0.tgz#a8c83e8cee83ef6a7383131519fe8031ad546386" - dependencies: - babel-runtime "6.x.x" - react-komposer "^1.9.0" - react-simple-di "^1.2.0" - marked-terminal@^1.6.2: version "1.7.0" resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-1.7.0.tgz#c8c460881c772c7604b64367007ee5f77f125904" @@ -5249,10 +4879,6 @@ mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.7: dependencies: mime-db "~1.26.0" -mime@1.2.x: - version "1.2.11" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" - mime@1.3.4, mime@^1.2.11, mime@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" @@ -5289,10 +4915,6 @@ mkdirp@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" -mobx@^2.3.4: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-2.7.0.tgz#cf3d82d18c0ca7f458d8f2a240817b3dc7e54a01" - moment@2.14.1, moment@2.x.x: version "2.14.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.14.1.tgz#b35b27c47e57ed2ddc70053d6b07becdb291741c" @@ -5345,12 +4967,6 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" -node-dir@^0.1.10: - version "0.1.16" - resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.16.tgz#d2ef583aa50b90d93db8cdd26fcea58353957fe4" - dependencies: - minimatch "^3.0.2" - node-emoji@^1.4.1: version "1.5.1" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.5.1.tgz#fd918e412769bf8c448051238233840b2aff16a1" @@ -5493,10 +5109,6 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" - normalize-path@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" @@ -5618,13 +5230,6 @@ object.entries@^1.0.3: function-bind "^1.1.0" has "^1.0.1" -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -5732,17 +5337,10 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: +os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -osenv@^0.1.0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - output-file-sync@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" @@ -5923,13 +5521,6 @@ pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" -podda@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/podda/-/podda-1.2.2.tgz#15b0edbd334ade145813343f5ecf9c10a71cf500" - dependencies: - babel-runtime "^6.11.6" - immutable "^3.8.1" - postcss-apply@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/postcss-apply/-/postcss-apply-0.3.0.tgz#a2f37c5bdfa881e4c15f4f245ec0cd96dd2e70d5" @@ -6149,7 +5740,7 @@ postcss-initial@^1.3.1: lodash.template "^4.2.4" postcss "^5.0.19" -postcss-load-config@^1.0.0, postcss-load-config@^1.2.0: +postcss-load-config@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.2.0.tgz#539e9afc9ddc8620121ebf9d8c3673e0ce50d28a" dependencies: @@ -6172,15 +5763,6 @@ postcss-load-plugins@^2.3.0: cosmiconfig "^2.1.1" object-assign "^4.1.0" -postcss-loader@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-1.1.0.tgz#4eb0bcbfc710b8b11406f3ea6650aaaa6e51b84f" - dependencies: - loader-utils "^0.2.16" - object-assign "^4.1.0" - postcss "^5.2.5" - postcss-load-config "^1.0.0" - postcss-loader@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-1.3.1.tgz#7907bdfe5e953cf4b6d97cbd8edcd17956369030" @@ -6431,7 +6013,7 @@ postcss@^4.1.7: js-base64 "~2.1.8" source-map "~0.4.2" -postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.19, postcss@^5.0.2, postcss@^5.0.21, postcss@^5.0.3, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.1.1, postcss@^5.2.0, postcss@^5.2.14, postcss@^5.2.15, postcss@^5.2.5: +postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.19, postcss@^5.0.2, postcss@^5.0.21, postcss@^5.0.3, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.1.1, postcss@^5.2.0, postcss@^5.2.14, postcss@^5.2.15: version "5.2.15" resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.15.tgz#a9e8685e50e06cc5b3fdea5297273246c26f5b30" dependencies: @@ -6486,7 +6068,7 @@ pretty-format@^19.0.0: dependencies: ansi-styles "^3.0.0" -private@^0.1.6, private@~0.1.5: +private@^0.1.6: version "0.1.7" resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" @@ -6583,7 +6165,7 @@ qs@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625" -qs@^6.1.0, qs@^6.2.0, qs@~6.3.0: +qs@~6.3.0: version "6.3.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.1.tgz#918c0b3bcd36679772baf135b1acb4c1651ed79d" @@ -6689,18 +6271,6 @@ react-copy-to-clipboard@^4.2.3: dependencies: copy-to-clipboard "^3" -react-docgen@^2.12.1: - version "2.13.0" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-2.13.0.tgz#7fcc4a3104ea8d4fd428383ba38df11166837be9" - dependencies: - async "^1.4.2" - babel-runtime "^6.9.2" - babylon "~5.8.3" - commander "^2.9.0" - doctrine "^2.0.0" - node-dir "^0.1.10" - recast "^0.11.5" - react-dom@15.5.0: version "15.5.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.5.0.tgz#86a8d6dcde388473815039de3840706e1f28f697" @@ -6716,13 +6286,16 @@ react-draggable@^2.1.0, react-draggable@^2.2.3: dependencies: classnames "^2.2.5" -react-fuzzy@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/react-fuzzy/-/react-fuzzy-0.3.3.tgz#9f6775393cd03bbd3c977651771abe16c8b29a81" +react-element-to-jsx-string@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-6.3.0.tgz#f598cbcef49338dd1ef211fc3c0e9c6a4ec91e26" dependencies: - babel-runtime "^6.5.0" - classnames "^2.2.3" - fuse.js "^2.2.0" + collapse-white-space "^1.0.0" + is-plain-object "^2.0.1" + lodash "^4.17.4" + sortobject "^1.0.0" + stringify-object "^3.1.0" + traverse "^0.6.6" react-height@^2.1.1: version "2.2.0" @@ -6739,47 +6312,12 @@ react-hot-loader@^1.3.0: react-hot-api "^0.4.5" source-map "^0.4.4" -react-inspector@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-1.1.2.tgz#192bc54f2be44f9fa0f29f183386f7f6e380f5ec" - dependencies: - babel-runtime "^6.9.2" - is-dom "^1.0.5" - -react-komposer@^1.9.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/react-komposer/-/react-komposer-1.13.1.tgz#4b8ac4bcc71323bd7413dcab95c831197f50eed0" - dependencies: - babel-runtime "6.x.x" - hoist-non-react-statics "1.x.x" - invariant "2.x.x" - mobx "^2.3.4" - shallowequal "0.2.x" - -react-komposer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/react-komposer/-/react-komposer-2.0.0.tgz#b964738014a9b4aee494a83c0b5b833d66072a90" - dependencies: - babel-runtime "^6.11.6" - hoist-non-react-statics "^1.2.0" - lodash.pick "^4.4.0" - react-stubber "^1.0.0" - shallowequal "^0.2.2" - react-lazy-cache@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/react-lazy-cache/-/react-lazy-cache-3.0.1.tgz#0dc64d38df1767ef77678c5c94190064cb11b0cd" dependencies: deep-equal "^1.0.1" -react-modal@^1.2.0, react-modal@^1.2.1: - version "1.6.5" - resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-1.6.5.tgz#f720d99bd81b1def5c2c32e0ffaa48bdaf484862" - dependencies: - element-class "^0.2.0" - exenv "1.2.0" - lodash.assign "^4.2.0" - react-motion@^0.4.5: version "0.4.7" resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.4.7.tgz#f77331ec7920bdb0d0cfc37eb6ffa10571bf42c7" @@ -6826,23 +6364,10 @@ react-router@^3.0.0: loose-envify "^1.2.0" warning "^3.0.0" -react-simple-di@^1.2.0: - version "1.2.0" - resolved "http://registry.npmjs.org/react-simple-di/-/react-simple-di-1.2.0.tgz#dde0e5bf689f391ef2ab02c9043b213fe239c6d0" - dependencies: - babel-runtime "6.x.x" - hoist-non-react-statics "1.x.x" - react-sortable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/react-sortable/-/react-sortable-1.2.0.tgz#5acd7e1910df665408957035acb5f2354519d849" -react-stubber@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/react-stubber/-/react-stubber-1.0.0.tgz#41ee2cac72d4d4fd70a63896da98e13739b84628" - dependencies: - babel-runtime "^6.5.0" - react-test-renderer@^15.4.2: version "15.4.2" resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.4.2.tgz#27e1dff5d26d0e830f99614c487622bc831416f3" @@ -6943,15 +6468,6 @@ readline2@^1.0.1: is-fullwidth-code-point "^1.0.0" mute-stream "0.0.5" -recast@^0.11.5: - version "0.11.22" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.22.tgz#dedeb18fb001a2bbc6ac34475fda53dfe3d47dfa" - dependencies: - ast-types "0.9.5" - esprima "~3.1.0" - private "~0.1.5" - source-map "~0.5.0" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -7055,10 +6571,6 @@ regenerator-runtime@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" -regenerator-runtime@^0.9.5: - version "0.9.6" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" - regenerator-transform@0.9.8: version "0.9.8" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.8.tgz#0f88bb2bc03932ddb7b6b7312e68078f01026d6c" @@ -7132,7 +6644,7 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@^2.64.0, request@^2.74.0, request@^2.79.0: +request@^2.64.0, request@^2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: @@ -7342,15 +6854,6 @@ send@0.14.2: range-parser "~1.2.0" statuses "~1.3.1" -serve-favicon@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.4.0.tgz#064dcdfdb0f250ae3b148eb18c8bbf3d185e3dd0" - dependencies: - etag "~1.8.0" - fresh "0.4.0" - ms "0.7.2" - parseurl "~1.3.1" - serve-index@^1.7.2: version "1.8.0" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.8.0.tgz#7c5d96c13fb131101f93c1c5774f8516a1e78d3b" @@ -7398,12 +6901,6 @@ sha.js@^2.3.6: dependencies: inherits "^2.0.1" -shallowequal@0.2.x, shallowequal@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-0.2.2.tgz#1e32fd5bcab6ad688a4812cb0cc04efc75c7014e" - dependencies: - lodash.keys "^3.1.2" - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -7414,7 +6911,7 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" -shelljs@^0.7.4, shelljs@^0.7.5: +shelljs@^0.7.5: version "0.7.6" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" dependencies: @@ -7448,10 +6945,6 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" @@ -7526,6 +7019,12 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" +sortobject@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/sortobject/-/sortobject-1.1.1.tgz#4f695d4d44ed0a4c06482c34c2582a2dcdc2ab34" + dependencies: + editions "^1.1.1" + source-list-map@^0.1.4, source-list-map@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" @@ -7542,7 +7041,7 @@ source-map@0.1.x, source-map@^0.1.41, source-map@~0.1.7: dependencies: amdefine ">=0.0.4" -source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3: +source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -7662,26 +7161,18 @@ string.prototype.codepointat@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz#6b26e9bd3afcaa7be3b4269b526de1b82000ac78" -string.prototype.padend@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.4.3" - function-bind "^1.0.2" - -string.prototype.padstart@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.0.0.tgz#5bcfad39f4649bb2d031292e19bcf0b510d4b242" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.4.3" - function-bind "^1.0.2" - string_decoder@^0.10.25, string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" +stringify-object@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.0.tgz#94370a135e41bc048358813bf99481f1315c6aa6" + dependencies: + get-own-enumerable-property-symbols "^1.0.1" + is-obj "^1.0.1" + is-regexp "^1.0.0" + stringstream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -7716,7 +7207,7 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -style-loader@0.13.1, style-loader@^0.13.0: +style-loader@^0.13.0: version "0.13.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.1.tgz#468280efbc0473023cd3a6cd56e33b5a1d7fc3a9" dependencies: @@ -7903,6 +7394,10 @@ tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" +traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + tree-kill@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.1.0.tgz#c963dcf03722892ec59cba569e940b71954d1729" @@ -8024,13 +7519,6 @@ url-join@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/url-join/-/url-join-0.0.1.tgz#1db48ad422d3402469a87f7d97bdebfe4fb1e3c8" -url-loader@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-0.5.7.tgz#67e8779759f8000da74994906680c943a9b0925d" - dependencies: - loader-utils "0.2.x" - mime "1.2.x" - url-parse@1.0.x: version "1.0.5" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" @@ -8091,7 +7579,7 @@ utils-merge@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" -uuid@^2.0.1, uuid@^2.0.2, uuid@^2.0.3: +uuid@^2.0.2, uuid@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" @@ -8188,7 +7676,7 @@ webpack-core@~0.6.9: source-list-map "~0.1.7" source-map "~0.4.1" -webpack-dev-middleware@^1.0.11, webpack-dev-middleware@^1.4.0, webpack-dev-middleware@^1.6.0: +webpack-dev-middleware@^1.0.11, webpack-dev-middleware@^1.4.0: version "1.10.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.1.tgz#c6b4cf428139cf1aefbe06a0c00fdb4f8da2f893" dependencies: @@ -8215,7 +7703,7 @@ webpack-dev-server@^1.16.2: supports-color "^3.1.1" webpack-dev-middleware "^1.4.0" -webpack-hot-middleware@^2.13.2, webpack-hot-middleware@^2.14.0: +webpack-hot-middleware@^2.14.0: version "2.17.0" resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.17.0.tgz#5af55fd2bc2f9a4392edd553f2a0fbebd4d75e78" dependencies: @@ -8239,7 +7727,7 @@ webpack-sources@^0.1.0: source-list-map "~0.1.7" source-map "~0.5.3" -webpack@^1.13.1, webpack@^1.14.0: +webpack@^1.14.0: version "1.14.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.14.0.tgz#54f1ffb92051a328a5b2057d6ae33c289462c823" dependencies: @@ -8351,14 +7839,6 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^1.1.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.1.tgz#7d45ba32316328dd1ec7d90f60ebc0d845bb759a" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" @@ -8376,12 +7856,6 @@ wtf-8@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" -xdg-basedir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" - dependencies: - os-homedir "^1.0.0" - xml-char-classes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d"