Skip to content

Commit

Permalink
Merge branch 'master' of github.com:metabase/metabase into non-root-p…
Browse files Browse the repository at this point in the history
…ath-v2
  • Loading branch information
tlrobinson committed Apr 13, 2017
2 parents 95635d4 + 1160971 commit de77294
Show file tree
Hide file tree
Showing 119 changed files with 4,850 additions and 5,604 deletions.
1 change: 0 additions & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
7 changes: 0 additions & 7 deletions .reduxrc

This file was deleted.

7 changes: 0 additions & 7 deletions .storybook/config.js

This file was deleted.

34 changes: 0 additions & 34 deletions .storybook/webpack.config.js

This file was deleted.

9 changes: 5 additions & 4 deletions OSX/Metabase/Backend/TaskHealthChecker.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -50,7 +50,7 @@ - (void)start {

[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];
Expand Down Expand Up @@ -91,8 +91,9 @@ - (void)checkHealth:(void(^)(BOOL healthy))completion {
}

- (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(@"");
Expand Down
6 changes: 5 additions & 1 deletion docs/administration-guide/databases/cratedb.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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.
22 changes: 13 additions & 9 deletions docs/api-documentation.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# API Documentation for Metabase v0.23.0-snapshot
# API Documentation for Metabase v0.24.0-snapshot

## `GET /api/activity/`

Expand Down Expand Up @@ -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`

Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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`

Expand All @@ -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`

Expand All @@ -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/`

Expand Down Expand Up @@ -1482,8 +1490,6 @@ Send a reset email when user has forgotten their password.

* **`remote-address`**

* **`request`**


## `POST /api/session/google_auth`

Expand Down Expand Up @@ -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`**
Expand Down Expand Up @@ -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:

Expand Down
15 changes: 10 additions & 5 deletions docs/operations-guide/running-metabase-on-elastic-beanstalk.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,19 @@ For the environment settings we want to make the following selections:

![ebenvtype](images/EBEnvType.png)

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.

Expand All @@ -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`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/metabase/admin/permissions/routes.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@

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";
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} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/metabase/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -74,6 +75,7 @@ function _init(reducers, getRoutes, callback) {
if (url === "/api/user/current") {
return
}
store.dispatch(clearCurrentUser());
store.dispatch(push("/auth/login"));
});

Expand Down
21 changes: 13 additions & 8 deletions frontend/src/metabase/auth/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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({
Expand Down Expand Up @@ -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

Expand All @@ -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) {
Expand Down Expand Up @@ -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({
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/metabase/components/Button.info.js
Original file line number Diff line number Diff line change
@@ -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>
};
14 changes: 14 additions & 0 deletions frontend/src/metabase/components/CheckBox.info.js
Original file line number Diff line number Diff line change
@@ -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 />
};
Loading

0 comments on commit de77294

Please sign in to comment.