Compare commits

..
Author SHA1 Message Date
vera-liuandGitHub 2d0ebeae1b [explorev2] Make chart container more responsive (#1724)
* Make chart container more responsive
 **Leave chart empty when theres error
 **Make all boolean fields auto-query chart when changed

* Replace forEach with some

* Added fields to autoQueryFields
2016-12-01 11:59:44 -08:00
BogdanandGitHub 1a16491971 Display full table name (schema + name) if possible. (#1728) 2016-12-01 14:57:39 -05:00
vera-liuandGitHub 7f4f250970 Redirects to login page if user not logged in at welcome page (#1723) 2016-11-30 17:41:02 -08:00
BogdanandGitHub 25acb78071 Pass schema to the select star query. (#1714) 2016-11-30 19:33:43 -05:00
BogdanandGitHub e822d5a1b7 Make edit / add / delete perms available to all users. (#1722)
* Make edit / add / delete perms available to all users.

* Add tests and restrict from editing the datasources.
2016-11-30 17:05:09 -05:00
vera-liuandGitHub 32fc0ff6d0 [Bugfix] autocomplete in sqleditor doesnot use newly loaded table columns (#1712) 2016-11-30 09:09:35 -08:00
Maxime Beauchemin 94dde075b3 v0.14.1 2016-11-29 15:57:05 -08:00
BogdanandGitHub 65e92327ab Druid hotfix. (#1710) 2016-11-29 18:11:59 -05:00
Maxime Beauchemin 0be02e67a5 Updating CHANGELOG 0.14.0 2016-11-29 15:10:21 -08:00
Maxime Beauchemin 7327c97e4c v0.14.0 2016-11-29 15:10:21 -08:00
vera-liuandGitHub 03b21dcf0a [explorev2] Bug fixes in Save Modal (#1707)
* Bug fixes in Save Modal
Issues solved:
 - Save button doesn't pass in gotodash
 - slice_name was passed in from store as original slice_name instead of
   new one in 'saveas' action
 - datasource_type wasn't passed in to defaultViz and defaultForm
   function

* Change css filename to exploreV2

* Moved out utils
2016-11-29 15:03:15 -08:00
BogdanandGitHub dc98c6739f Implement table name extraction. (#1598)
* Implement table name extraction tests.

* Address comments.

* Fix tests and reimplement the token processing.

* Exclude aliases.

* Clean up print statements and code.

* Reverse select test.

* Fix failing test.

* Test JOINs

* refactore as a class

* Check for permissions in SQL Lab.

* Implement permissions check for the datasources in sql_lab

* Address comments.
2016-11-29 15:43:36 -05:00
BogdanandGitHub fcb870728d Add per schema permissions. (#1698)
* Add per schema permissions.

* Address comments.

* Add schema_access perms to the alpha and admin

* Create permissions on addition databases and datasources.

* Remove hybrid_property. Linter complains.
2016-11-29 14:16:55 -05:00
vera-liuandGitHub 7919428a1e Vliu explorev2 bugs (#1701)
* Fixed table_name does not exist in druid

* Make Chart container scrollable for large chart

* Fixed bug of action buttons not clickable in heatmap

* Solve codeclimate issue

* Limit overflow to x
2016-11-29 10:31:11 -08:00
Alanna ScottandGitHub 3496a80f5a make stack trace more readable (#1672)
* make stack trace more readable

* remove ascii_art import

* remove ascii_art.py
2016-11-28 21:05:37 -08:00
Alanna ScottandGitHub 56b917a5c2 [explore-v2] fix errors on table view (#1675)
* render table name if in table view

* only render fave star and edit button if slice, not table

* fix error when table view

* use [table-name] - untitled format

* remove extra fave star
2016-11-28 21:04:43 -08:00
Alanna ScottandGitHub 18c43aaea2 make chart title larger, fix explore actions btn spacing (#1680) 2016-11-28 20:12:44 -08:00
Maxime BeaucheminandGitHub c43fc38f69 [druid] fix having clause (#1694) 2016-11-28 16:43:45 -08:00
BogdanandGitHub c07f0ab9c7 Config programmatic roles in the config.py (#1664)
* Config programmatic roles in the config.py,

* Add sql_lab.
2016-11-28 19:29:30 -05:00
Maxime BeaucheminandGitHub 1c429b27bc Fixing issue #1689 (#1696) 2016-11-28 16:25:09 -08:00
Maxime BeaucheminandGitHub b7019ad4f3 [sqllab] bugfix SouthPane doesn't update as expected (#1699)
* [sqllab] bugfix SouthPane doesn't update as expected

* Linting
2016-11-28 16:24:02 -08:00
the-dcruzandMaxime Beauchemin 84e8f741ae Add 'Save As' feature for dashboards (#1669)
* Add 'Save As' feature for dashboards

* Address code review comments
2016-11-28 08:34:14 -08:00
Nicolas NoéandMaxime Beauchemin e3a9b393c2 Missing merge_perm function. Fixes 1691. (#1692) 2016-11-28 08:27:41 -08:00
Riccardo MagliocchettiandMaxime Beauchemin 16aba517e4 Use smaller size for node max_old_space_size (#1679)
This makes the difference from being killed by OOM on a 8GB machine
or working.
2016-11-25 14:10:40 -08:00
Riccardo MagliocchettiandMaxime Beauchemin 205928e6df docs: fix python-redis link markup (#1683) 2016-11-25 14:09:14 -08:00
vera-liuandGitHub 39ce4aa049 Added filter in ControlPanelsContainer for explore V2 (#1647)
* Added filter in ControlPanelsContainer

* Move function for getting url params object to utils

* Fixed python test

* Move Filter to separate component

* Added specs and made changes based on comments

* Moved specs to right folder
2016-11-23 09:51:19 -08:00
Maxime BeaucheminandGitHub cef4a8296a [sqllab] adding a sql preprocessor for Presto (#1670)
* [sqllab] adding a sql preprocessor for Presto

* fixing tests
2016-11-22 21:24:38 -08:00
vera-liuandGitHub b370ef0229 Rerender chart without clicking query button for fields (#1658)
* For some fields we would like to re-render chart once field is
  * changed, saving user the time to click query button
  * Such fields are stored in an array in store, could add more fields in
  * the future
2016-11-22 17:08:52 -08:00
vera-liuandGitHub 6b80f5bb35 Get sections to render when switching datasource (#1660)
* Get sections to render when switching datasource
 - Move sectionsToRender in store and use is for defaultFormData
 - Change some SelectField to FreeFormSelect according to forms.py

* Solved the css not found problem in staging

* Fixed js tests
2016-11-22 14:55:32 -08:00
vera-liuandGitHub bdae570a69 Temperary fix of a slice bug (#1648) 2016-11-22 14:54:49 -08:00
vera-liuandGitHub face5245a9 Make explore container resize with browser window (#1608) 2016-11-22 14:36:41 -08:00
vera-liuandGitHub db1ed2a765 Calculate height dynamically using jquery for scrollable sqllab (#1611)
* Calculate height dynamically using jquery for scrollable sqllab components

* Move editorHeight to App.jsx

* Calculate height dynamically for query search
2016-11-22 13:21:07 -08:00
vera-liuandGitHub 10982dec3c Make QueryTable scrollable in Query Search page (#1656) 2016-11-22 11:19:23 -08:00
vera-liuandGitHub 6825e75681 Fixed bug with querylink passing sql object instead of string (#1659) 2016-11-22 11:09:32 -08:00
vera-liuandGitHub bd6a439e0b [QuerySearch] Add loading status to QuerySearch page (#1657)
* Add loading state to QuerySearch
 * Move ajax call to ComponentDidMount
 * Show loading image during ajax call
2016-11-21 13:18:18 -08:00
BogdanandGitHub c90dd4902f Programatically sync the role with user list. (#1619) 2016-11-21 13:06:43 -05:00
Robert KingstonandMaxime Beauchemin 868e5c45fe Redirect URL requests with "caravel" to "superset" (#1651)
* Redirect URL requests with "caravel" to "superset"

* Adding extra line break
2016-11-20 10:36:51 -08:00
Maxime BeaucheminandGitHub 7e1852ee88 User profile pages (favorites, created content, recent activity, security & access) (#1615)
* Super

* User profile page

* Fixing python style

* Python unit tests

* Touchups and js tests

* Addressing comments
2016-11-19 21:23:44 -08:00
Maxime BeaucheminandGitHub 5ae98bc7c9 Improving jinja2 security by using SandboxedEnvironment (#1632)
http://jinja.pocoo.org/docs/dev/sandbox/#sandbox
2016-11-18 17:14:30 -08:00
BogdanandGitHub 1624e7de7d Add all_tables endpoint to allow airpal / superset perm sync. (#1614) 2016-11-18 20:14:26 -05:00
BogdanandGitHub 7a98f84890 Admin / Alpha permission cleanup and fixes. (#1645) 2016-11-18 19:53:19 -05:00
Alanna ScottandGitHub 9b181280d4 include jQuery and bootstrap (#1642) 2016-11-18 16:22:46 -08:00
vera-liuandGitHub 38e94b9e43 Save modal component for explore v2 (#1612)
* Added specs for SaveModal

* Move datasource_id and datasource_name to form_data

* Add comments

* Deleted redundant fetchDashboard

* Replcae has_key for python3

* More react and less jquery

* Added alert for save slice

* Small changes based on comments

* Use react bootstrap
2016-11-18 14:56:02 -08:00
BogdanandGitHub dc25bc6f4d Fix alpha permission checks. (#1641) 2016-11-18 17:22:24 -05:00
vera-liuandGitHub f64a205603 Use Alert for visualization error (#1639) 2016-11-18 13:38:14 -08:00
vera-liuandGitHub a8480f5492 Added Alert for ControlPanel and ChartContainer (#1626)
* Added Alert for ControlPanel and ChartContainer

Done:
 - Add alert for Control Panel when fetch_datasource_metadata failes
 - Add alert for Chart Container when update_explore query fails

* Changed color to warning-yellow

* Solve linter issue

* Fixed indent and delete error_redirect
2016-11-18 11:17:06 -08:00
vera-liuandGitHub 0acf26b37c Fixed a bug with switching viz_type in exploreV2 (#1631)
- Issue: when switching from a viz_type outside nvd3 to a viz_type in
 nvd3, the Chart Container doesn't draw new graph
 - Fix: The reason was somehow the function inside nv.addGraph() wasn't
   called, extract the function outside and explicitly calling it solve
   the problem
2016-11-18 10:23:00 -08:00
Alanna ScottandGitHub 2c068a1a15 increase space between fieldsset rows (#1629) 2016-11-18 10:08:50 -08:00
Maxime BeaucheminandGitHub b961c95121 dim visualization during refresh (#1636) 2016-11-18 10:06:07 -08:00
Dody Suria WijayaandMaxime Beauchemin 82693211f0 Update faq.rst (#1637)
Related to #1557
2016-11-18 10:04:44 -08:00
the-dcruzandAlanna Scott e5467462cb Make nvd3 refresh smoother. (#1618) 2016-11-18 09:43:36 -08:00
Alanna ScottandGitHub ab5a4102cd [dashboard] give user feedback when there are unsaved changes (#1633)
* show alert and use dialog window if there are unsaved changes.

* add container class to alert
2016-11-18 09:37:01 -08:00
vera-liuandGitHub d5ef937b31 Fixed bugs with viz in exploreV2 (#1609)
* Fixed bugs with viz in exploreV2

Done:
 - fix typo in pie viz
 - add metrics/groupby to dist_bar viz
 - fix typo in heatmap viz
 - add big_number_total to viz
 - fixed problem with fetching columns for datasource
 - add sqlaTimeSeries to viz
 - change row_limit and limit from number to strings so that we
 don't need to parse integers in bootstrap data

* Fix python tests

* Added order_bars checkbox for dist_bar viz
2016-11-17 12:31:36 -08:00
Maxime BeaucheminandGitHub bce02e3f51 [security] improving the security scheme (#1587)
* [security] improving the security scheme

* Addressing comments

* improving docs

* Creating security module to organize things

* Moving CLI to its own module

* perms

* Materializung perms

* progrss

* Addressing comments, linting
2016-11-17 11:58:33 -08:00
Alanna ScottandGitHub aad9744d85 add new screenshots (#1589) 2016-11-17 11:45:40 -08:00
Alanna ScottandGitHub 506b781f3a [explore-v2] add fave star and edit button to chart header (#1623)
* add fave star to chart title

* add TooltipWrapper, and css for icons

* fix linting
2016-11-17 10:53:44 -08:00
Maxime BeaucheminandGitHub 267fd5b9bc [table viz] adding support for pagination (#1616)
* [table viz] adding support for pagination

* linting
2016-11-17 10:05:36 -08:00
Maxime BeaucheminandGitHub c362f2869e More Dashboard UX unit tests (#1603) 2016-11-17 10:05:08 -08:00
vera-liuandGitHub 4f7f437527 Vliu put datasource in store (#1610)
* Move datasource from global store object to form_data

* Moved datasource_id  and datasource_name to form_data

* Refetch defaultFormData when switching datasource

* Fixed js tests
2016-11-17 09:26:25 -08:00
Maxime BeaucheminandGitHub ab5da5ba28 [table viz] allow sorting on any column (#1601)
* [table viz] allow sorting on any column

* explorev2
2016-11-17 07:15:18 -08:00
vera-liuandGitHub 7531bb8942 Fixed dashboard controls for standalone bug (#1617) 2016-11-16 17:54:50 -08:00
vera-liuandGitHub 811ee8ccdc Deleted unused components in exploreV2 (#1613)
* Deleted unused components in exploreV2

* Deleted constants.js
2016-11-16 14:33:00 -08:00
vera-liuandGitHub 51cb485ce3 Add standalone to reactified dashboard page (#1596) 2016-11-16 13:22:14 -08:00
vera-liuandGitHub 83d08b8b8f Get query button working in explorev2 (#1581)
* Get query buttonw working in explorev2

 - Create new endpoint for updating explore viz
 - Send over new form_data when query button is pressed

* Added endpoint test

* Changes based on comments

* Added docstring for endpoint, and query spec

* Remove white space around docstring
2016-11-16 13:21:53 -08:00
Maxime Beauchemin ed3d44d591 Changelog entries for 0.13.2 2016-11-15 16:54:45 -08:00
Maxime Beauchemin 895fe23203 v0.13.2 2016-11-15 16:23:39 -08:00
André CruzandMaxime Beauchemin af04a560c8 Moved check to the correct place. (#1606) 2016-11-15 10:38:03 -08:00
Maxime Beauchemin 9124a17e86 Removing ascii_art.p from code coverage analysis 2016-11-15 08:50:08 -08:00
Maxime BeaucheminandGitHub 99b0d4c111 Fix MySql time grain issue (#1590)
* Fix MySql time grain issue

* linting

* linting
2016-11-14 21:35:10 -08:00
Maxime Beauchemin 84b98c234f Adding Greenplum to supported dbs 2016-11-14 15:46:24 -08:00
Maxime Beauchemin bcc1428ebf Updating CODECLIMATE_REPO_TOKEN to new location 2016-11-14 12:45:58 -08:00
vera-liuandGitHub 2133056c04 Added different Select Fields (#1583)
* Added different Select Fields
 - Switched FormGroup to react-select
 - Added multi and freeform to select, now it can take customized user
   input and insert it as options

* Fixed tests

* Small nit based on comments
2016-11-13 14:11:52 -08:00
Robert KingstonandMaxime Beauchemin 4155a9d7f9 Removing broken link to old docker image (#1591)
Need to re-add if/when Kochalex updates to using Superset
2016-11-12 19:32:39 -08:00
vera-liuandGitHub ed4825523c Fixed a bug with new dashboard (#1585) 2016-11-11 17:28:07 -08:00
Maxime Beauchemin fdbb2bbdab fixing the build 2016-11-11 16:24:57 -08:00
Mazdak BandMaxime Beauchemin c064d6d847 Correct part_fields variable name (#1586) 2016-11-11 16:20:04 -08:00
Maxime Beauchemin d33874bd3d [hotfix] postgres issue when slice_id is missing 2016-11-11 09:57:34 -08:00
Maxime BeaucheminandGitHub 96d32dd11f Improve Druid metadata fetching resilience (#1584) 2016-11-11 09:46:48 -08:00
Maxime Beauchemin d6bc354ff3 [hotfix] fix support for presto DATE and TIMESTAMP type 2016-11-11 00:39:20 +00:00
Maxime Beauchemin 7325a4fb4b [hotfix] table view not group by without orderby fails 2016-11-10 23:54:51 +00:00
Maxime Beauchemin 90f00c5b29 Minor documentation touchups 2016-11-10 11:27:56 -08:00
Maxime Beauchemin 8539c423ea v0.13.1 2016-11-10 10:01:31 -08:00
Maxime Beauchemin e9bfbfce84 Removing boat pic from README 2016-11-10 09:41:09 -08:00
Maxime Beauchemin 6e4f0664cb [hotfix] lint 2016-11-10 09:09:40 -08:00
Maxime Beauchemin 3c920c9d94 [hotfix] datatables import issues 2016-11-10 09:07:53 -08:00
Maxime BeaucheminandGitHub 15b67b2c6c [WiP] rename project from Caravel to Superset (#1576)
* Change in files

* Renamin files and folders

* cleaning up a single piece of lint

* Removing boat picture from docs

* add superset word mark

* Update rename note in docs

* Fixing images

* Pinning datatables

* Fixing issues with mapbox-gl

* Forgot to rename one file

* Linting

* v0.13.0

* adding pyyaml to dev-reqs
2016-11-09 23:08:22 -08:00
Maxime Beauchemin 973537fd9a [hotfix] resizing widgets 2016-11-09 14:52:39 -08:00
vera-liuandMaxime Beauchemin d70a74479d Make Sqllab a one-page app -- body not scrollable (#1551)
* Make Sqllab a one-page app -- body not scrollable

* Add scroll-container and scroll-content in main.css
2016-11-09 14:21:43 -08:00
Maxime BeaucheminandGitHub 946e4b750a Reactifying the dashboard (#1572) 2016-11-09 14:21:23 -08:00
vera-liuandMaxime Beauchemin 9789e3fb9b Bind data preview tabs to sql editor (#1573) 2016-11-09 14:21:06 -08:00
Maxime Beauchemin 6a15679d87 [hotfix] encode csv to utf-8 2016-11-09 11:46:15 -08:00
vera-liuandGitHub ad1cd5577c Pass values from global store to fields in exploreV2 (#1561)
* Link fields to store by firing setFormData action

* Moved onChange to ControlPanelsContainer, retrieve defaultFormData from fields in store

* Pass data from store to checkbox/select/text Field

* Fixed tests

* Changed reducer back to old Object.assign() style
2016-11-09 09:01:17 -08:00
Dirk KellyandMaxime Beauchemin 55668ca621 Link to database-urls in databaseadd view (#1480) 2016-11-09 08:49:01 -08:00
Alanna ScottandGitHub 0c221a28d1 add slice_name and table_name for title (#1567) 2016-11-09 08:48:26 -08:00
Maxime BeaucheminandGitHub a475551b23 [sqllab] bind alt+enter shortcut in AceEditor to run a query (#1554) 2016-11-09 08:42:13 -08:00
Riccardo MagliocchettiandMaxime Beauchemin bad7676414 Bump cryptography dependency to 1.5.3 (#1569)
As the 1.5 release branch builds with OpenSSL 1.1.x
2016-11-09 08:41:57 -08:00
Alanna ScottandGitHub 51c0470f0b [explore v2] populate dynamic select field options (#1543)
* pass field options in viz json

* move field options to fetch_datasource_metadata

* on control panels container mount, fetch datasource meta data and set dynamic field choices

* render options for select fields

* use component class rather than sic

* fix linting

* fix whitespace

* delete unused var

* only render fields once datasource meta has returned

* fix typo

* add datasources and fix column formatting

* fix tests

* never used function

* fix tests

* add test for fetch_datasource_metadata

* remove unneeded props
2016-11-08 15:55:49 -08:00
vera-liuandGitHub 4530047c76 Added action buttons to Chart Container of explore V2 (#1562) 2016-11-08 15:22:20 -08:00
Alanna ScottandGitHub 1bf83c3bf7 [explore-v2] render columns based on length of fieldSets array (#1559)
* render columns based on length of fieldSets array

* fix tests
2016-11-08 13:52:24 -08:00
vera-liuandGitHub bb6ab11001 Vliu link form data explore v2 (#1540)
* Put default form_data and viz in store

* Link fields to store by firing setFormData action

* Fixed tests for Container and actions

* Moved onChange to ControlPanelsContainer, retrieve defaultFormData from fields in store

* Deleted switch statement in reducer

* Removed resetFormData and refactored setFormData in reducers

* Added text for fields

* Changed test statements
2016-11-08 10:28:51 -08:00
Maxime BeaucheminandGitHub e4bd1884d3 [druid] adding support for dimensionspecs (#1545)
More about it here:
http://druid.io/docs/latest/querying/dimensionspecs.html

fixes https://github.com/airbnb/caravel/issues/1086
2016-11-07 17:05:41 -08:00
vera-liuandGitHub 4014a48f7d Added cache prop to ResultSet (#1552)
* Added cache prop to ResultSet for distiguishing query result and datapreview results

* small nit

* Only cache results.data locally
2016-11-07 15:28:46 -08:00
pinkythalli97andMaxime Beauchemin 97ded32415 Update linting instructions. (#1478)
flake8 changes tests lints only the test dir.
2016-11-06 08:26:14 -08:00
vera-liuandGitHub 593ac081f0 Added scroll bar and option to collapse for Sql Editor tool bar (#1532)
* Added scroll bar and option to collapse for Sql Editor tool bar
Done:
 - Added scroll-bar to Sql Editor tool bar
 - Added hide/expand tool bar option to dropdown menu of tab

* Add more margin to give space to scroll-bar

* Add scroll to right panel independently
2016-11-04 15:58:11 -07:00
vera-liuandGitHub 69f0a4e1cb Put data preview in south pane (#1486)
* Put data preview in south pane

Before: data preview of a selected table appears as a modal, but for
some cases users may want to view data and edit sql at the same time

After:
 - data preview of a selected table pops up a new tab in South Pane
 - data are saved to local state and flushed in global store in
   ResultSet component

* Moved dataPreviewId to table object

* Put back preview icon for fetching preview data

* Revert "Put back preview icon for fetching preview data"

This reverts commit b6f5dcfe64.

* Added option to retrieve preview results after refresh
2016-11-04 14:21:51 -07:00
Glen SchraderandMaxime Beauchemin 757e7de60c add oracle time_grains (#1544) 2016-11-04 09:52:06 -07:00
Maxime Beauchemin 1d7d5469a9 [hotfix] remove failing Druid test 2016-11-04 09:47:02 -07:00
vera-liuandGitHub 98afc3e590 Added setFilter(), containerID and getFilter() to (#1360)
mock slice object in exploreV2

 - filter_box in exploreV2 was broken because containerID and
   getFilter() were not defined in the mock of slice object
2016-11-03 21:14:08 -07:00
Maxime Beauchemin ea189790f1 [hotfix] druid dist_bar viz issues with non-str x values 2016-11-04 00:59:41 +00:00
BogdanandGitHub 62987077fa Read the user origin specification. (#1541) 2016-11-03 17:33:06 -07:00
Maxime Beauchemin 3b9f7cb3f1 [hotfix] groupby may be a set 2016-11-04 00:08:18 +00:00
vera-liuandGitHub 5882c7e344 Added jquery methods to ChartContainer to get world_map viz working in exploreV2 (#1443) 2016-11-03 15:50:36 -07:00
vera-liuandGitHub 77b6e2cd2e Get pivot table working in explore v2 (#1432)
* Use jquery calls in find() and html() of slice mock to
Get pivot_table viz working

* Borrowed code from caravel.js into error callback
2016-11-03 13:53:45 -07:00
Alanna ScottandGitHub 88b1f956c7 [explore-v2] handle field overrides (#1535)
* pass all props to *Field components

* s/fieldSetOverrides/fieldOverrides

* handle field overrides
2016-11-03 13:38:17 -07:00
Alanna ScottandGitHub d9b49ca2bc [exploreV2] remove /exploreV2 endpoint, add v2 bootstrap data to /explore endpoint (#1536)
* remove exploreV2 endpoint, add v2 bootstrap data to explore endpoint

* delete empty line

* move bootstrap data inside elif condition
2016-11-03 13:37:29 -07:00
Alanna ScottandGitHub 4156ad5a30 [explore-v2] control panel fixes (#1529)
* make fieldset conditions more clear

* make label required

* use render* pattern

* use slugify util for turning labels into ids

* use field rather than html

* don't need panel-title class here
2016-11-02 21:51:56 -07:00
BogdanandGitHub ae46561648 Support week_ending_saturday for Druid. (#1491)
* Support week_ending_saturday for Druid.

* Use period granularity

* Use ISO 8601 for period definitions.

* Fix tests

* More flexibility for the freeform choices.
2016-11-02 18:45:10 -07:00
Maxime BeaucheminandGitHub 1700a807e9 [sqllab] templating refactor (#1504)
* Add support for jinja templates in WHERE/HAVING clauses

* Generalizing

* bugfix
2016-11-02 13:22:07 -07:00
shashank singhandMaxime Beauchemin 0bab15b213 Update INTHEWILD.md (#1526)
Added Faasos
2016-11-02 13:21:16 -07:00
Alanna ScottandGitHub 38d3075554 [explore V2] render all control panels and fields dynamically for each vis type (#1493)
* export functions directly rather than object at the bottom

* move viztypes to controlPanelMappings, add fieldset rows and section data

* for each viz type, render a controlPanelsContainer, controlPanelSections, FieldSetRows, and FieldsSets

* add comments, move mappings to store

* organize store and add default sections

* render all the needed sections

* add tooltip to sections

* remove console log

* use only panel panel-default, not panel-body, no need the padding

* render fields for all fields in field set

* add the rest of the control panel sections and field overrides

* fix naming

* add fieldTypes array

* don't use default section

* pass only needed state via mapStateToProps

* fix code climate errors

* linting

* move field components to their own files

* render field sets as lists

* fix field components

* use SFC

* update modal trigger test to be more accurate

* add FieldSetRow test

* add test for controlpanelsContainer

* fix test

* make code climate happy

* add freeform select field
2016-11-02 12:57:44 -07:00
Maxime BeaucheminandGitHub 1b124bfb87 [druid] optimize Druid queries where possible (#1517)
* [druid] optimize Druid queries where possible

Trying to use timeseries, topn where possible, falling back on 2-phases
groupby only where needed

* Fixing py3 bug
2016-11-02 11:25:33 -07:00
plumbeoandMaxime Beauchemin cdf4dd0302 Add yearly and quarterly granularities to mysql engine backend (#1518) 2016-11-02 08:00:34 -07:00
vera-liuandGitHub a13bed2db6 Moved sqllab tests from core_tests to sqllab_tests (#1502)
* Moved sqllab tests from core_tests to sqllab_tests

* Minor changes based on comments
2016-11-01 20:48:31 -07:00
vera-liuandGitHub 26318f94fe Moved queriesArray from render() to local state (#1505)
* Moved queriesArray from render() to local state, so that QueriesArray
is only reloaded only during switching tabs or queries object is updated.

* Changed object comparison function to take length into consideration
2016-11-01 19:40:09 -07:00
BogdanandGitHub 769fb0820f Strip sql and remove ; for csv download. (#1508) 2016-11-01 15:03:42 -07:00
vera-liuandGitHub 52380534f3 Moved ajax call for fetching table metadata from SqlEditorLeftBar to actions (#1494) 2016-11-01 09:00:24 -07:00
Maxime BeaucheminandGitHub 2fd2526046 Add support for jinja templates in WHERE/HAVING clauses (#1442) 2016-11-01 08:16:06 -07:00
Maxime BeaucheminandGitHub 61509bbd44 [sqllab] surfacing more table metadata (indices, pk, fks) (#1485)
* Expose more table/column metadata

* [sqllab] expose more table metadata

* more tests
2016-10-31 23:52:37 -07:00
Maxime Beauchemin 76499afd8d [pep8] allowing 90 chars per line 2016-10-31 21:22:44 -07:00
Maxime BeaucheminandGitHub 4023f328f7 [sqllab] run only the part of the query that is selected (#1479) 2016-10-31 21:07:46 -07:00
BogdanandGitHub 4f49cb555b Celery uses separate db engine with NullPool. (#1492)
* Celery uses separate db engine with NullPool.

* Address comment
2016-10-31 16:02:12 -07:00
BogdanandGitHub 4dc959a3e4 Revert "NullPool for the celery worker." (#1488) 2016-10-31 10:02:07 -07:00
Ron BakerandMaxime Beauchemin 518fbf562c Minor Fixes (#1484)
* Fix typo accomodate

* Fix typo calender

* Fix typo dimentions
2016-10-30 16:55:56 -07:00
Maxime Beauchemin 49828d3d9d add step to pypi build/push 2016-10-29 21:11:16 -07:00
willgrovesandMaxime Beauchemin 248e6a7b05 fix name for postgresql (#1482) 2016-10-29 20:34:10 -07:00
BogdanandGitHub 5561e6b770 Fix celery module import in comments. (#1474) 2016-10-29 14:08:23 -07:00
Maxime BeaucheminandGitHub ab083b86f3 [sqllab] slide animations when adding/removing/toggling TableElement (#1472)
* [sqllab] slide animations when adding/removing/toggling TableElement

* Adressing comments
2016-10-29 07:48:17 -07:00
Maxime BeaucheminandGitHub 4bf525222a [sqllab] add autocomplete to AceEditor for table and column names (#1475)
* [sqllab] add autocomplete to AceEditor for table and column names

* addressing comment about getCompletions as a component method
2016-10-28 21:35:49 -07:00
vera-liuandGitHub 45efcb381c Added time filter to query search page (#1329)
* Added time filter to query search page

* Added start date

* Updated python endpoint test

* changed spec

* Added specs and tests

* Modified python/js tests and some function/file names
based on code review comments

* Resolved conflicts in DashboardSelect_spec and QuerySearch_spec

* Break python tests for separate functions, Move sql queries to setUp()

* Get around eslint error for spec

* Small changes based on comments
2016-10-28 14:12:53 -07:00
BogdanandGitHub 07a7736c71 NullPool for the celery worker. (#1465) 2016-10-28 14:01:24 -07:00
vera-liuandGitHub d2826ab7af Added checkbox in dist_bar viz to enable sorting of bars based on x axis labels (#1379)
* Added order bars option for dist_bar viz

* Make order_bar checkbox to cover half the colum and translate the description
2016-10-28 10:33:57 -07:00
Maxime Beauchemin 6ab769f382 CHANGELOG for 0.12.0 2016-10-28 09:48:28 -07:00
465 changed files with 12692 additions and 6191 deletions
+8 -8
View File
@@ -6,7 +6,7 @@ engines:
eslint:
enabled: true
config:
config: caravel/assets/.eslintrc
config: superset/assets/.eslintrc
pep8:
enabled: true
fixme:
@@ -19,17 +19,17 @@ engines:
ratings:
paths:
- "**.py"
- "caravel/assets/**.js"
- "caravel/assets/**.jsx"
- "superset/assets/**.js"
- "superset/assets/**.jsx"
exclude_paths:
- ".*"
- "**.pyc"
- "**.gz"
- "env/"
- "tests/"
- "caravel/assets/images/"
- "caravel/assets/vendor/"
- "caravel/assets/node_modules/"
- "caravel/assets/javascripts/dist/"
- "caravel/migrations"
- "superset/assets/images/"
- "superset/assets/vendor/"
- "superset/assets/node_modules/"
- "superset/assets/javascripts/dist/"
- "superset/migrations"
- "docs/"
+8 -4
View File
@@ -1,22 +1,25 @@
*.pyc
caravel/assets/coverage/*
yarn-error.log
_modules
superset/assets/coverage/*
changelog.sh
.DS_Store
.coverage
_build
_static
_images
caravel/bin/caravelc
_modules
superset/bin/supersetc
env_py3
.eggs
build
*.db
tmp
caravel_config.py
superset_config.py
local_config.py
env
dist
caravel.egg-info/
superset.egg-info/
app.db
*.bak
.idea
@@ -27,3 +30,4 @@ app.db
*.js.map
node_modules
npm-debug.log
yarn.lock
+1 -2
View File
@@ -16,8 +16,7 @@ pep8:
full: true
ignore-paths:
- docs
- caravel/migrations/env.py
- caravel/ascii_art.py
- superset/migrations/env.py
ignore-patterns:
- ^example/doc_.*\.py$
- (^|/)docs(/|$)
+2
View File
@@ -0,0 +1,2 @@
[pycodestyle]
max-line-length = 90
+3 -3
View File
@@ -24,10 +24,10 @@ env:
before_install:
- npm install -g npm@'>=3.9.5'
before_script:
- mysql -e 'drop database if exists caravel; create database caravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci' -u root
- mysql -e 'drop database if exists superset; create database superset DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci' -u root
- mysql -u root -e "CREATE USER 'mysqluser'@'localhost' IDENTIFIED BY 'mysqluserpassword';"
- mysql -u root -e "GRANT ALL ON caravel.* TO 'mysqluser'@'localhost';"
- psql -c 'create database caravel;' -U postgres
- mysql -u root -e "GRANT ALL ON superset.* TO 'mysqluser'@'localhost';"
- psql -c 'create database superset;' -U postgres
- psql -c "CREATE USER postgresuser WITH PASSWORD 'pguserpassword';" -U postgres
- export PATH=${PATH}:/tmp/hive/bin
install:
+230
View File
@@ -1,5 +1,235 @@
## Change Log
### 0.14.0 (2016/11/29 23:03 +00:00)
- [03b21dc](https://github.com/airbnb/superset/commit/03b21dcf0a3fc18e1290f7770004d3b74df8cef3) [explorev2] Bug fixes in Save Modal (#1707) (@vera-liu)
- [dc98c67](https://github.com/airbnb/superset/commit/dc98c6739fcccc8edc60ef7e761cb1491005f644) Implement table name extraction. (#1598) (@bkyryliuk)
- [fcb8707](https://github.com/airbnb/superset/commit/fcb870728db69bbee092d20c3f78cb7785fe2e61) Add per schema permissions. (#1698) (@bkyryliuk)
- [7919428](https://github.com/airbnb/superset/commit/7919428a1e02457a50ae00439e827f996403f71c) Vliu explorev2 bugs (#1701) (@vera-liu)
- [3496a80](https://github.com/airbnb/superset/commit/3496a80f5a85a0b66e59ec259ed13ca9ba3d5ba0) make stack trace more readable (#1672) (@ascott)
- [56b917a](https://github.com/airbnb/superset/commit/56b917a5c206d3083d9d9d3d0606b976c64b6044) [explore-v2] fix errors on table view (#1675) (@ascott)
- [18c43aa](https://github.com/airbnb/superset/commit/18c43aaea2f889e50211b22f0a68269f314bcafa) make chart title larger, fix explore actions btn spacing (#1680) (@ascott)
- [c43fc38](https://github.com/airbnb/superset/commit/c43fc38f69d6284729cd47368e796117adcc1d1b) [druid] fix having clause (#1694) (@mistercrunch)
- [c07f0ab](https://github.com/airbnb/superset/commit/c07f0ab9c72430f5892f701d6cba35718ef322ad) Config programmatic roles in the config.py (#1664) (@bkyryliuk)
- [1c429b2](https://github.com/airbnb/superset/commit/1c429b27bc425aa8ba0f8cc6b43887cfb91dcd15) Fixing issue #1689 (#1696) (@mistercrunch)
- [b7019ad](https://github.com/airbnb/superset/commit/b7019ad4f343ecbd5d33ce4a5800a72a9f4301b6) [sqllab] bugfix SouthPane doesn't update as expected (#1699) (@mistercrunch)
- [84e8f74](https://github.com/airbnb/superset/commit/84e8f741ae969888c4f2501ada132f58bdcfb249) Add 'Save As' feature for dashboards (#1669) (@the-dcruz)
- [e3a9b39](https://github.com/airbnb/superset/commit/e3a9b393c26ab173fe3ffe3dd14191705cab7119) Missing merge_perm function. Fixes 1691. (#1692) (@niconoe)
- [16aba51](https://github.com/airbnb/superset/commit/16aba517e4640300c9a71f6186776671540bc488) Use smaller size for node max_old_space_size (#1679) (@xrmx)
- [205928e](https://github.com/airbnb/superset/commit/205928e6df892060cdd3ffe0af6a1217a848f301) docs: fix python-redis link markup (#1683) (@xrmx)
- [39ce4aa](https://github.com/airbnb/superset/commit/39ce4aa049fffef3b9f6e368d64130ae85cb86d8) Added filter in ControlPanelsContainer for explore V2 (#1647) (@vera-liu)
- [cef4a82](https://github.com/airbnb/superset/commit/cef4a8296a6a9d46503dd63e268be3a35e9e8e91) [sqllab] adding a sql preprocessor for Presto (#1670) (@mistercrunch)
- [b370ef0](https://github.com/airbnb/superset/commit/b370ef0229377c6b85f78d9ba080d00ff6dba58e) Rerender chart without clicking query button for fields (#1658) (@vera-liu)
- [6b80f5b](https://github.com/airbnb/superset/commit/6b80f5bb35e497c79fe458b25ba87266e3c0f3bf) Get sections to render when switching datasource (#1660) (@vera-liu)
- [bdae570](https://github.com/airbnb/superset/commit/bdae570a69cd948987b05fed2e7653a221ef0d80) Temperary fix of a slice bug (#1648) (@vera-liu)
- [face524](https://github.com/airbnb/superset/commit/face5245a99d13089b9fa4cfa7521ee2ca6b209c) Make explore container resize with browser window (#1608) (@vera-liu)
- [db1ed2a](https://github.com/airbnb/superset/commit/db1ed2a765d317e55377f2550f169b78f981b4a0) Calculate height dynamically using jquery for scrollable sqllab (#1611) (@vera-liu)
- [10982de](https://github.com/airbnb/superset/commit/10982dec3c69f1bed709b38616417eada995d2f4) Make QueryTable scrollable in Query Search page (#1656) (@vera-liu)
- [6825e75](https://github.com/airbnb/superset/commit/6825e75681b1249d066d9fa0bf0dca9f1824bb24) Fixed bug with querylink passing sql object instead of string (#1659) (@vera-liu)
- [bd6a439](https://github.com/airbnb/superset/commit/bd6a439e0b2a3a76f8aece91f11a7eee2ebf6d29) [QuerySearch] Add loading status to QuerySearch page (#1657) (@vera-liu)
- [c90dd49](https://github.com/airbnb/superset/commit/c90dd4902f18bb11c46bc38b8f70bfc14cfc2171) Programatically sync the role with user list. (#1619) (@bkyryliuk)
- [868e5c4](https://github.com/airbnb/superset/commit/868e5c45fed8e090750dffe88660f3943f373c19) Redirect URL requests with "caravel" to "superset" (#1651) (@kingo55)
- [7e1852e](https://github.com/airbnb/superset/commit/7e1852ee883628d38b2e3bb71e2b2b03fad41ba3) User profile pages (favorites, created content, recent activity, security & access) (#1615) (@mistercrunch)
- [5ae98bc](https://github.com/airbnb/superset/commit/5ae98bc7c9b432683d03d30a30631a6efd7a78a3) Improving jinja2 security by using SandboxedEnvironment (#1632) (@mistercrunch)
- [1624e7d](https://github.com/airbnb/superset/commit/1624e7de7dd50f1c4f5fdd9153adac4ba5b983d2) Add all_tables endpoint to allow airpal / superset perm sync. (#1614) (@bkyryliuk)
- [7a98f84](https://github.com/airbnb/superset/commit/7a98f848909ca2099e29d3f485fd299037142e65) Admin / Alpha permission cleanup and fixes. (#1645) (@bkyryliuk)
- [9b18128](https://github.com/airbnb/superset/commit/9b181280d44171cb0c724a07f50488eb08f98e72) include jQuery and bootstrap (#1642) (@ascott)
- [38e94b9](https://github.com/airbnb/superset/commit/38e94b9e43f82c682f311fe1563c8f502ae4157a) Save modal component for explore v2 (#1612) (@vera-liu)
- [dc25bc6](https://github.com/airbnb/superset/commit/dc25bc6f4d5eeb74665dd353bafda5d97ef5faa1) Fix alpha permission checks. (#1641) (@bkyryliuk)
- [f64a205](https://github.com/airbnb/superset/commit/f64a2056038e96883e31419df5fcd4fa396dffb6) Use Alert for visualization error (#1639) (@vera-liu)
- [a8480f5](https://github.com/airbnb/superset/commit/a8480f54922775992a28edd7878b1cfa7690264e) Added Alert for ControlPanel and ChartContainer (#1626) (@vera-liu)
- [0acf26b](https://github.com/airbnb/superset/commit/0acf26b37c7a59cb976cf7a929caf7cc5a1a968e) Fixed a bug with switching viz_type in exploreV2 (#1631) (@vera-liu)
- [2c068a1](https://github.com/airbnb/superset/commit/2c068a1a1583fa61db2f1797b0fcb2618cd6dbe3) increase space between fieldsset rows (#1629) (@ascott)
- [b961c95](https://github.com/airbnb/superset/commit/b961c95121e5e4d4342a2926746dbf8a62bd77ea) dim visualization during refresh (#1636) (@mistercrunch)
- [8269321](https://github.com/airbnb/superset/commit/82693211f0545affbdc306561a1abb4478c2de9a) Update faq.rst (#1637) (@dodysw)
- [e546746](https://github.com/airbnb/superset/commit/e5467462cb73630a9b487891845ab1f01245f2a8) Make nvd3 refresh smoother. (#1618) (@the-dcruz)
- [ab5a410](https://github.com/airbnb/superset/commit/ab5a4102cd8921ca2df234bfa6133973ba83a425) [dashboard] give user feedback when there are unsaved changes (#1633) (@ascott)
- [d5ef937](https://github.com/airbnb/superset/commit/d5ef937b315f4afc679349369b4e7ac7455748f0) Fixed bugs with viz in exploreV2 (#1609) (@vera-liu)
- [bce02e3](https://github.com/airbnb/superset/commit/bce02e3f518237c03273e3ed4d9d1a13d9f8f6a9) [security] improving the security scheme (#1587) (@mistercrunch)
- [aad9744](https://github.com/airbnb/superset/commit/aad9744d85b50721d55d5770aad70ba1ee397ede) add new screenshots (#1589) (@ascott)
- [506b781](https://github.com/airbnb/superset/commit/506b781f3a6048b433c12d25c1dbce614b5bd31b) [explore-v2] add fave star and edit button to chart header (#1623) (@ascott)
- [267fd5b](https://github.com/airbnb/superset/commit/267fd5b9bc4f21a55c4664ae8c3ee717cc1be82c) [table viz] adding support for pagination (#1616) (@mistercrunch)
- [c362f28](https://github.com/airbnb/superset/commit/c362f2869e012a4eeb9b76ff654ee3e82a190979) More Dashboard UX unit tests (#1603) (@mistercrunch)
- [4f7f437](https://github.com/airbnb/superset/commit/4f7f43752798f57daa8cd8b8ed8a9cbc9c948000) Vliu put datasource in store (#1610) (@vera-liu)
- [ab5da5b](https://github.com/airbnb/superset/commit/ab5da5ba2811ac6c2350c7d0534dd209906318af) [table viz] allow sorting on any column (#1601) (@mistercrunch)
- [7531bb8](https://github.com/airbnb/superset/commit/7531bb89429547fb541c36fe365791cd742d82a1) Fixed dashboard controls for standalone bug (#1617) (@vera-liu)
- [811ee8c](https://github.com/airbnb/superset/commit/811ee8ccdc76a2630a4c8014df26558391b981fe) Deleted unused components in exploreV2 (#1613) (@vera-liu)
- [51cb485](https://github.com/airbnb/superset/commit/51cb485ce3e8cb80c72ec8c732281a78441396fd) Add standalone to reactified dashboard page (#1596) (@vera-liu)
- [83d08b8](https://github.com/airbnb/superset/commit/83d08b8b8f7c73cbf4de25cadeab93dd3fdfc2fc) Get query button working in explorev2 (#1581) (@vera-liu)
- [ed3d44d](https://github.com/airbnb/superset/commit/ed3d44d5919fc2ba739cf8d82e75e2680630646d) Changelog entries for 0.13.2 (@mistercrunch)
### 0.13.2 (2016/11/16 00:23 +00:00)
- [895fe23](https://github.com/airbnb/superset/commit/895fe23203a85a4590f84625507849ce63d69f30) v0.13.2 (@mistercrunch)
- [af04a56](https://github.com/airbnb/superset/commit/af04a560c887ecbcee40b53c358ee9c2ad2f44ad) Moved check to the correct place. (#1606) (@edevil)
- [9124a17](https://github.com/airbnb/superset/commit/9124a17e864b8b2eb109af33fe1b8aad809069da) Removing ascii_art.p from code coverage analysis (@mistercrunch)
- [99b0d4c](https://github.com/airbnb/superset/commit/99b0d4c111b66f6da0eb9991b54b375e2fbeecc4) Fix MySql time grain issue (#1590) (@mistercrunch)
- [84b98c2](https://github.com/airbnb/superset/commit/84b98c234f852550ecf536e4a6e7ce2d7ebc5df6) Adding Greenplum to supported dbs (@mistercrunch)
- [bcc1428](https://github.com/airbnb/superset/commit/bcc1428ebf1cf7e83c93e351858bee3cfbb2e9c2) Updating CODECLIMATE_REPO_TOKEN to new location (@mistercrunch)
- [2133056](https://github.com/airbnb/superset/commit/2133056c04d20807ea0c503d0fed235ee20e94bb) Added different Select Fields (#1583) (@vera-liu)
- [4155a9d](https://github.com/airbnb/superset/commit/4155a9d7f996d09ebdfc8df0db3dcbe9ccf9b529) Removing broken link to old docker image (#1591) (@kingo55)
- [ed48255](https://github.com/airbnb/superset/commit/ed4825523ca54309272f044826f383c2606456a1) Fixed a bug with new dashboard (#1585) (@vera-liu)
- [fdbb2bb](https://github.com/airbnb/superset/commit/fdbb2bbdab5e5dbb2f3496b67eb227dc3dc5f2a7) fixing the build (@mistercrunch)
- [c064d6d](https://github.com/airbnb/superset/commit/c064d6d8475b07a63a3b5ca7b4dbd248a437f6ed) Correct part_fields variable name (#1586) (@geraneum)
- [d33874b](https://github.com/airbnb/superset/commit/d33874bd3d9ffffca7f4726a29c3eb9de2a68d42) [hotfix] postgres issue when slice_id is missing (@mistercrunch)
- [96d32dd](https://github.com/airbnb/superset/commit/96d32dd11f29afa3590b79d8683aaddd05f48a02) Improve Druid metadata fetching resilience (#1584) (@mistercrunch)
- [d6bc354](https://github.com/airbnb/superset/commit/d6bc354ff3e2f24aeb459dbc1413371f2b072306) [hotfix] fix support for presto DATE and TIMESTAMP type (@mistercrunch)
- [7325a4f](https://github.com/airbnb/superset/commit/7325a4fb4ba08f554454534fe9efe3d0eea5a6ce) [hotfix] table view not group by without orderby fails (@mistercrunch)
- [90f00c5](https://github.com/airbnb/superset/commit/90f00c5b292ff83802d35bac49a26e6b257de409) Minor documentation touchups (@mistercrunch)
### 0.13.1 (2016/11/10 18:01 +00:00)
- [8539c42](https://github.com/airbnb/superset/commit/8539c423ea61d84e8e0a81317275713103f99a8a) v0.13.1 (@mistercrunch)
- [e9bfbfc](https://github.com/airbnb/superset/commit/e9bfbfce84b5ab851c839c70adf5298b2538e9dc) Removing boat pic from README (@mistercrunch)
- [6e4f066](https://github.com/airbnb/superset/commit/6e4f0664cb49d5e7144dadba7ccda548cf58e905) [hotfix] lint (@mistercrunch)
- [3c920c9](https://github.com/airbnb/superset/commit/3c920c9d943540cc8ed0d6e3dfd2ae0eba3acb70) [hotfix] datatables import issues (@mistercrunch)
- [15b67b2](https://github.com/airbnb/superset/commit/15b67b2c6c3c2982f6620fce5d30bd05951458f7) [WiP] rename project from Caravel to Superset (#1576) (@mistercrunch)
### 0.13.0 (2016/11/10 05:37 +00:00)
- [973537f](https://github.com/airbnb/superset/commit/973537fd9a60766a6ee99bd2e7080aa7db21f540) [hotfix] resizing widgets (@mistercrunch)
- [d70a744](https://github.com/airbnb/superset/commit/d70a74479df87908de7a7b4df7c24c6b267bf9e3) Make Sqllab a one-page app -- body not scrollable (#1551) (@vera-liu)
- [946e4b7](https://github.com/airbnb/superset/commit/946e4b750afeebbfa16e6ce7e9fc61575136b237) Reactifying the dashboard (#1572) (@mistercrunch)
- [9789e3f](https://github.com/airbnb/superset/commit/9789e3fb9b658e1f38080915132ae43c541e68e9) Bind data preview tabs to sql editor (#1573) (@vera-liu)
- [6a15679](https://github.com/airbnb/superset/commit/6a15679d876c5c76d177b624a5d69da80ac75a3f) [hotfix] encode csv to utf-8 (@mistercrunch)
- [ad1cd55](https://github.com/airbnb/superset/commit/ad1cd5577c231e4100f5a214fe7a4d372de96a04) Pass values from global store to fields in exploreV2 (#1561) (@vera-liu)
- [55668ca](https://github.com/airbnb/superset/commit/55668ca6217f52924288f3849a0aa54c28d40ce1) Link to database-urls in databaseadd view (#1480) (@dirkkelly)
- [0c221a2](https://github.com/airbnb/superset/commit/0c221a28d10abc8cf4e929e50fd788a56136a9cf) add slice_name and table_name for title (#1567) (@ascott)
- [a475551](https://github.com/airbnb/superset/commit/a475551b23d5830ab2945f615328f31d48df36ca) [sqllab] bind alt+enter shortcut in AceEditor to run a query (#1554) (@mistercrunch)
- [bad7676](https://github.com/airbnb/superset/commit/bad7676414662b28a4b72eb680fbf42a5c6281a5) Bump cryptography dependency to 1.5.3 (#1569) (@xrmx)
### airbnb_prod.0.12.0.1 (2016/11/08 23:55 +00:00)
- [51c0470](https://github.com/airbnb/superset/commit/51c0470f0be438312e90f2efb1f2e37291a30ce4) [explore v2] populate dynamic select field options (#1543) (@ascott)
- [4530047](https://github.com/airbnb/superset/commit/4530047c769ba6d5953ef1547b8507c62f657942) Added action buttons to Chart Container of explore V2 (#1562) (@vera-liu)
- [1bf83c3](https://github.com/airbnb/superset/commit/1bf83c3bf78de422df1b21c3049d106b1cb29385) [explore-v2] render columns based on length of fieldSets array (#1559) (@ascott)
- [bb6ab11](https://github.com/airbnb/superset/commit/bb6ab110013f2e29933fb9a70d6891d4486eb49d) Vliu link form data explore v2 (#1540) (@vera-liu)
- [e4bd188](https://github.com/airbnb/superset/commit/e4bd1884d34a1949b986410ebc385b75945afff8) [druid] adding support for dimensionspecs (#1545) (@mistercrunch)
- [4014a48](https://github.com/airbnb/superset/commit/4014a48f7df9fe166c77132f3d8d83cf615ac176) Added cache prop to ResultSet (#1552) (@vera-liu)
- [97ded32](https://github.com/airbnb/superset/commit/97ded32415e9e32ba2c6a7e4556a0ed96034244a) Update linting instructions. (#1478) (@pinkythalli97)
- [593ac08](https://github.com/airbnb/superset/commit/593ac081f06af5e95dc784597473d42aea52cf28) Added scroll bar and option to collapse for Sql Editor tool bar (#1532) (@vera-liu)
- [69f0a4e](https://github.com/airbnb/superset/commit/69f0a4e1cb2c7775617a15a5ba709836a568210c) Put data preview in south pane (#1486) (@vera-liu)
- [757e7de](https://github.com/airbnb/superset/commit/757e7de60cf7aa04f15160942ceaadb46daa15b5) add oracle time_grains (#1544) (@gschrader)
- [1d7d546](https://github.com/airbnb/superset/commit/1d7d5469a925690d4b4fd1e7a3cdf37779acffb6) [hotfix] remove failing Druid test (@mistercrunch)
- [98afc3e](https://github.com/airbnb/superset/commit/98afc3e590ef25d08fecf159bf4411ac292e95f0) Added setFilter(), containerID and getFilter() to (#1360) (@vera-liu)
- [ea18979](https://github.com/airbnb/superset/commit/ea189790f160dc6419ac97d8f6740afa62ba6e78) [hotfix] druid dist_bar viz issues with non-str x values (@mistercrunch)
- [6298707](https://github.com/airbnb/superset/commit/62987077fa31ebbedafbaa745b36527b7df0c9f7) Read the user origin specification. (#1541) (@bkyryliuk)
- [3b9f7cb](https://github.com/airbnb/superset/commit/3b9f7cb3f1d0dd1387d01204259b5ce7f2469793) [hotfix] groupby may be a set (@mistercrunch)
- [5882c7e](https://github.com/airbnb/superset/commit/5882c7e3447a06875e63b4424994a0a5e5fc58a5) Added jquery methods to ChartContainer to get world_map viz working in exploreV2 (#1443) (@vera-liu)
- [77b6e2c](https://github.com/airbnb/superset/commit/77b6e2cd2e796d063dbc6d42934143bf45bba8b0) Get pivot table working in explore v2 (#1432) (@vera-liu)
- [88b1f95](https://github.com/airbnb/superset/commit/88b1f956c7cd8bd457d04648447fb23700b859ae) [explore-v2] handle field overrides (#1535) (@ascott)
- [d9b49ca](https://github.com/airbnb/superset/commit/d9b49ca2bc1eab3221fc329d0ab5a9b421746110) [exploreV2] remove /exploreV2 endpoint, add v2 bootstrap data to /explore endpoint (#1536) (@ascott)
- [4156ad5](https://github.com/airbnb/superset/commit/4156ad5a3054f5194ea94b6fc146e53e4ccb0b57) [explore-v2] control panel fixes (#1529) (@ascott)
- [ae46561](https://github.com/airbnb/superset/commit/ae465616482c8e76634728bcd6990fcfb3b752ad) Support week_ending_saturday for Druid. (#1491) (@bkyryliuk)
- [1700a80](https://github.com/airbnb/superset/commit/1700a807e9a8ebc4cfb2749293308be733e42473) [sqllab] templating refactor (#1504) (@mistercrunch)
- [0bab15b](https://github.com/airbnb/superset/commit/0bab15b2132ae769ce81519f2d27858ad6d0b187) Update INTHEWILD.md (#1526) (@shashanksingh)
- [38d3075](https://github.com/airbnb/superset/commit/38d307555487d84b60dd6169006bbb6aa9fc87a5) [explore V2] render all control panels and fields dynamically for each vis type (#1493) (@ascott)
- [1b124bf](https://github.com/airbnb/superset/commit/1b124bfb87862a25a7b904e05929c23f0c61d0e2) [druid] optimize Druid queries where possible (#1517) (@mistercrunch)
- [cdf4dd0](https://github.com/airbnb/superset/commit/cdf4dd03024cff40f17845ab9b57ae6a6070e197) Add yearly and quarterly granularities to mysql engine backend (#1518) (@plumbeo)
- [a13bed2](https://github.com/airbnb/superset/commit/a13bed2db685a9fa913676bd71b570c81a190c6e) Moved sqllab tests from core_tests to sqllab_tests (#1502) (@vera-liu)
- [26318f9](https://github.com/airbnb/superset/commit/26318f94fef888a4b54a022bbbd44f269cfbf9b3) Moved queriesArray from render() to local state (#1505) (@vera-liu)
- [769fb08](https://github.com/airbnb/superset/commit/769fb0820fbefd1e58ced40fa79d2d7c923091e4) Strip sql and remove ; for csv download. (#1508) (@bkyryliuk)
- [5238053](https://github.com/airbnb/superset/commit/52380534f360cbb0e3d7ab46889066cd2df47440) Moved ajax call for fetching table metadata from SqlEditorLeftBar to actions (#1494) (@vera-liu)
- [2fd2526](https://github.com/airbnb/superset/commit/2fd252604689693c957a1b6875a18872a59d5ec8) Add support for jinja templates in WHERE/HAVING clauses (#1442) (@mistercrunch)
- [61509bb](https://github.com/airbnb/superset/commit/61509bbd446bbcc21f4f79229c88d82441d1fb98) [sqllab] surfacing more table metadata (indices, pk, fks) (#1485) (@mistercrunch)
- [76499af](https://github.com/airbnb/superset/commit/76499afd8d28289cac0cf0f2d7316e6e64bab089) [pep8] allowing 90 chars per line (@mistercrunch)
- [4023f32](https://github.com/airbnb/superset/commit/4023f328f7893fbe4b0e0af1612d598e1c931f72) [sqllab] run only the part of the query that is selected (#1479) (@mistercrunch)
- [4f49cb5](https://github.com/airbnb/superset/commit/4f49cb555be68c5e1daed817d1137fbd1c3f4e3f) Celery uses separate db engine with NullPool. (#1492) (@bkyryliuk)
- [4dc959a](https://github.com/airbnb/superset/commit/4dc959a3e4464ed38d4b5e580ae1fc009178e185) Revert "NullPool for the celery worker." (#1488) (@bkyryliuk)
- [518fbf5](https://github.com/airbnb/superset/commit/518fbf562cca638cf14d97dfae92756091630eb2) Minor Fixes (#1484) (@ronbak)
- [49828d3](https://github.com/airbnb/superset/commit/49828d3d9d51c02b13ce916a85cfe912bee43c54) add step to pypi build/push (@mistercrunch)
- [248e6a7](https://github.com/airbnb/superset/commit/248e6a7b05fd4ef30c4f2c006d0df935da84e052) fix name for postgresql (#1482) (@willgroves)
- [5561e6b](https://github.com/airbnb/superset/commit/5561e6b77086ffafb58c363a22e97a5800590e47) Fix celery module import in comments. (#1474) (@bkyryliuk)
- [ab083b8](https://github.com/airbnb/superset/commit/ab083b86f35c6f01dfa16bf84c8c212bf21743cf) [sqllab] slide animations when adding/removing/toggling TableElement (#1472) (@mistercrunch)
- [4bf5252](https://github.com/airbnb/superset/commit/4bf525222a609320acc28232f25b7651c54cfda0) [sqllab] add autocomplete to AceEditor for table and column names (#1475) (@mistercrunch)
- [45efcb3](https://github.com/airbnb/superset/commit/45efcb381c0d0b53b9de72a3437ec980b201bab0) Added time filter to query search page (#1329) (@vera-liu)
- [07a7736](https://github.com/airbnb/superset/commit/07a7736c71050c20dc04661ab3f1d21f58cb3b39) NullPool for the celery worker. (#1465) (@bkyryliuk)
- [d2826ab](https://github.com/airbnb/superset/commit/d2826ab7af4da1b36816150b71002ed966c553cd) Added checkbox in dist_bar viz to enable sorting of bars based on x axis labels (#1379) (@vera-liu)
- [6ab769f](https://github.com/airbnb/superset/commit/6ab769f38227788fbffb1eadb0e43c656f7c1da0) CHANGELOG for 0.12.0 (@mistercrunch)
### 0.12.0 (2016/10/28 16:40 +00:00)
- [3e1cd2b](https://github.com/airbnb/caravel/commit/3e1cd2bdcabce219dc01c6ce7b80850ecd50f9ba) v0.12.0 (@mistercrunch)
- [22784b7](https://github.com/airbnb/caravel/commit/22784b7f069d59e3fa7df03cfea84df9e147af13) run_specific_test: take the test as parameter (#1469) (@xrmx)
- [c492261](https://github.com/airbnb/caravel/commit/c4922615eb707228cdc1badd49bf2d293c74a699) [sqllab] add column sort feature to TableElement (#1467) (@mistercrunch)
- [7307dda](https://github.com/airbnb/caravel/commit/7307ddad3c9b60ec2178286cbc27a302e158de83) Highlight affected slices for filter change in dashboard view (#1439) (@vera-liu)
- [c7ba143](https://github.com/airbnb/caravel/commit/c7ba143d039aff61302017329860cd3db432b0f6) Fix typo in sqllab docs (@mistercrunch)
- [b242063](https://github.com/airbnb/caravel/commit/b24206387b09946df40a834db2d3b1deae21f865) [sqllab] optimizing React (#1438) (@mistercrunch)
- [64d1964](https://github.com/airbnb/caravel/commit/64d196442fcd17f098ba6d71da8bad1f84bdbb5a) Added dashboard standalone page (#1429) (@vera-liu)
- [5944643](https://github.com/airbnb/caravel/commit/5944643da67acb1ec38ed8d52f9ae6f58d7549ac) [sqllab] add support for Jinja templating (#1426) (@mistercrunch)
- [8c5e495](https://github.com/airbnb/caravel/commit/8c5e4952727d7ff6e96e61c1a38de2e600b02208) Add github issue template (#1436) (@xrmx)
- [bb23685](https://github.com/airbnb/caravel/commit/bb23685b9db623be89714153361ee3b03b46a39d) Added average metric AVG() to default metrics (#1413) (@vera-liu)
- [940659b](https://github.com/airbnb/caravel/commit/940659bc14ed276a68478b66055356cf3b48ba29) [sqllab] some frontend tests (#1400) (@mistercrunch)
- [7c59337](https://github.com/airbnb/caravel/commit/7c5933732bcb199e486ac8c4bf7ecec71013117d) Filter immune slices array stores strings. (#1402) (@bkyryliuk)
- [89df2fc](https://github.com/airbnb/caravel/commit/89df2fcf76bdaca34dfef19a9d5bb752a9859c6d) Adjusted top margin of heatmap plot to get it working in V2 (#1361) (@vera-liu)
- [174a199](https://github.com/airbnb/caravel/commit/174a199c30ad6c24505092975b814688e8a37292) [hotfix] Query search is unreachable (@mistercrunch)
- [6f1e7c3](https://github.com/airbnb/caravel/commit/6f1e7c3016b53cf8d3c0e28dba3538861fe56086) Added url shortner for sharing query link (#1314) (@vera-liu)
- [9f81e23](https://github.com/airbnb/caravel/commit/9f81e23f8f0698c94a9f4c34b49cbf3dda1e2e87) Fixed css class not being used by slice container (#1359) (@vera-liu)
- [19fab6e](https://github.com/airbnb/caravel/commit/19fab6eea71bbd97974a0ef8dd74451011f3862f) Get table viz work in explore v2: Added d3 format to mock slice (#1353) (@vera-liu)
- [63161b1](https://github.com/airbnb/caravel/commit/63161b11c347d5a6d62f7ae7dc91fa3c30b5dc93) [sqllab] proper, quoted, select * on the server side (#1404) (@mistercrunch)
- [4f886d6](https://github.com/airbnb/caravel/commit/4f886d65ecc208149cf9b7663492a81df868dcc2) Fix None view_menues in permissions. (#1409) (@bkyryliuk)
- [62e0e19](https://github.com/airbnb/caravel/commit/62e0e195e8eaa53afa41a5fec89cc4486a7114a3) [docfix] d3.format docs have moved (@mistercrunch)
- [e9d4749](https://github.com/airbnb/caravel/commit/e9d4749f4470aee294f1351baa9422173a2a62c8) [hotfix] sqllab presto (@mistercrunch)
- [93f8e7d](https://github.com/airbnb/caravel/commit/93f8e7d8e9b25a1aaf07e2b0c3772c327e523f0e) Fix the js build running out of heap space (#1408) (@mistercrunch)
- [3dea6e0](https://github.com/airbnb/caravel/commit/3dea6e0da538ed1c0a7761ccbf97bd8f12ac7f2f) [sqllab] adding more descriptive labels to left panel (#1407) (@mistercrunch)
- [6fb3b30](https://github.com/airbnb/caravel/commit/6fb3b305ad23c27d0555ded2ab80820000fdec50) [sqllab] add support for results backends (#1377) (@mistercrunch)
- [7dfe891](https://github.com/airbnb/caravel/commit/7dfe891cc1d294bd55982d63c9c1eb8f9e9e4c25) [hotfix] timeseries_limit_metric: Not a valid choice (@mistercrunch)
- [5c3966a](https://github.com/airbnb/caravel/commit/5c3966a32d454a2fc7fcabd75c66594662361586) Override the role with perms for given datasources. (#1399) (@bkyryliuk)
- [c198535](https://github.com/airbnb/caravel/commit/c198535292869ae1ced6d66d08de536188be7e05) Change slice ids in the position json during dashboard import. (#1380) (@bkyryliuk)
- [ece69fb](https://github.com/airbnb/caravel/commit/ece69fbb75086cb8855789881a32c6daca4be483) Fix migration for make creator owners (#1262) (@ShengyaoQian)
- [458651f](https://github.com/airbnb/caravel/commit/458651fa3e0098f35412772b622e7c0b63d34299) Add parens for custom where and having (#1337) (@yejianye)
- [b2f7081](https://github.com/airbnb/caravel/commit/b2f7081c6f3dde80846493330f1ec1e5fa3a414c) bumping versions of JS packages to latest (#1352) (@mistercrunch)
- [c255e89](https://github.com/airbnb/caravel/commit/c255e89219c209b5a5371134fbb9a9b90036ded4) [sqllab] show partition metadata for Presto (#1342) (@mistercrunch)
- [2edce5b](https://github.com/airbnb/caravel/commit/2edce5bf8afa7b74fdafd8ab8a2e6394d46e6391) Enable "Run Query in New Tab" in SQL Lab (#1343) (@nickbarnwell)
- [8f29944](https://github.com/airbnb/caravel/commit/8f299448ea954f75f576399f6bc113dd8ac1c824) [bugfix] text as subquery fails with 'Series Limit' (#1347) (@mistercrunch)
- [ecb951b](https://github.com/airbnb/caravel/commit/ecb951bb7474b9c829d0eef12792f6c146757dba) Specify the metric to order by for Series Limit (#1351) (@mistercrunch)
- [0dff6a9](https://github.com/airbnb/caravel/commit/0dff6a9030d8f2ff7a03654258f3b02f01d9d57e) Add quarter time grain to postgresql (#1362) (@xrmx)
- [2095095](https://github.com/airbnb/caravel/commit/2095095895d9cf5bc8131fb51fbb4868fae124dc) Fixed big number issue (#1355) (@vera-liu)
- [4fc8a17](https://github.com/airbnb/caravel/commit/4fc8a17f2ae18dcc2be778e52b3d3ed7be29e95a) [hotfix] use instead of prod for Travis build, take 3 (@mistercrunch)
- [3cb737f](https://github.com/airbnb/caravel/commit/3cb737f8c890b018bd6b3275047a02f79abb7444) [hotfix] use instead of prod for Travis build, take2 (@mistercrunch)
- [7449aa8](https://github.com/airbnb/caravel/commit/7449aa813b8b695e6dc3b06eb25004bc2a55614f) [hotfix] use instead of prod for Travis build (@mistercrunch)
- [7a3bcc2](https://github.com/airbnb/caravel/commit/7a3bcc227cccdec756404ab6140a6ba0d3882419) [bugfix] NaN issue in Big Number viz (#1346) (@mistercrunch)
- [b669a14](https://github.com/airbnb/caravel/commit/b669a140816b950237b7d66b73ac6af392f28d8a) [explore-v2] make chart container work with existing visualization files (#1333) (@ascott)
- [9db4cc8](https://github.com/airbnb/caravel/commit/9db4cc8c6d0422f28357dc4283089ee3dde9a08e) add node/npm versions to contributing.md (#1344) (@ascott)
- [65c744f](https://github.com/airbnb/caravel/commit/65c744f2424d111e950b385630bd8a13b3fa003e) Fix utc time calculation if provided datetime has tz info (#1287) (@labeneator)
- [82bcadf](https://github.com/airbnb/caravel/commit/82bcadf7f829183fbf6feca81dcc6c69f08c358c) Moving 'CSS TEmplates' to the Manage menu category (#1336) (@mistercrunch)
- [f0f8478](https://github.com/airbnb/caravel/commit/f0f8478922cbe8e4ac754fddcfd6183032bbb893) Revert "Override the role with perms for give datasources." (#1345) (@bkyryliuk)
- [40e7057](https://github.com/airbnb/caravel/commit/40e7057bcec55421275d0121d365a2e4f2d38a29) Override the role with perms for give datasources. (#1335) (@bkyryliuk)
- [11a8e35](https://github.com/airbnb/caravel/commit/11a8e3591d281a8cde6fb0ab57ed54ec97035e23) Some dashboard import/export fixes. (#1340) (@bkyryliuk)
- [5bea398](https://github.com/airbnb/caravel/commit/5bea3986b26359eb98c62246c34729e2d0cc5a1b) [hotfix] handling json errors in explore view (@mistercrunch)
- [89cb726](https://github.com/airbnb/caravel/commit/89cb726284b2a4f2707f26d3004ef9ae59b33970) [hotfix] explore errors are not raise properly 2 (@mistercrunch)
- [4e9392d](https://github.com/airbnb/caravel/commit/4e9392d21bf7f43e8189eb4478cf9d737c3616bd) [hotfix] explore errors are not raise properly (@mistercrunch)
- [b785d27](https://github.com/airbnb/caravel/commit/b785d27241e9f22dcb6a880414500ce8f9e67eb3) Taking out object spread operator (#1311) (@vera-liu)
- [451860a](https://github.com/airbnb/caravel/commit/451860afcab971a0a16b521a7c884d1c4d910986) remove #app styling (#1312) (@ascott)
- [4cf4e38](https://github.com/airbnb/caravel/commit/4cf4e3805c4d0a217fa6232ba1d6ee3a68c86ed2) Bugfix when there's only date filter in FilterBox (no groupby) (#1326) (@yejianye)
- [ef2670c](https://github.com/airbnb/caravel/commit/ef2670ca32e8ba0a04f9dc7899db55812e2f9b46) Using inheritance scheme to organize db specific code (#1294) (@mistercrunch)
- [8626c80](https://github.com/airbnb/caravel/commit/8626c80d3a491b842f8262c5807154903c107747) Stop duplicating datasources (#1321) (@bkyryliuk)
- [5cb3cc2](https://github.com/airbnb/caravel/commit/5cb3cc2ed8c8c2f0295da7ecdf8ec33a526acee1) polyfill es2015 in older browsers and for phantomjs (#1323) (@ascott)
- [73cd2ea](https://github.com/airbnb/caravel/commit/73cd2ea3b17574f8fef1112aa5e5b39f843882f6) Import / export of the dashboards. (#1197) (@bkyryliuk)
- [cd2ab42](https://github.com/airbnb/caravel/commit/cd2ab42abcd2ea5f93dd285321c448c97abf4580) do not overwrite the stored password with the masked password (#1209) (@dennisobrien)
- [bf1f5ea](https://github.com/airbnb/caravel/commit/bf1f5ea3de23a62eca4f823474119e4c15270738) [sqllab] use encodeURIComponent for copy query URL (#1317) (@mistercrunch)
- [79460ab](https://github.com/airbnb/caravel/commit/79460abdd230b2d53a9f2da15ac5160ba6db400b) [SQLLab] Fix the usage of Redux DevTools Enhancer (#1278) (@zalmoxisus)
- [1e6e144](https://github.com/airbnb/caravel/commit/1e6e144d24da38aef0d306889dc3b8f962ca4b32) Fixed viewing dashboards as anonymous (#1320) (@Rapsutin)
- [fe66557](https://github.com/airbnb/caravel/commit/fe66557bbb4848feed762e859abcd5884d72d369) [explore-v2] hook up ExploreViewContainer to state and add specs (#1300) (@ascott)
- [f8e2ce6](https://github.com/airbnb/caravel/commit/f8e2ce6ff367047405be60d7cbcfd68e4f4521d8) Change status color in tab to match with success (#1247) (@vera-liu)
- [1967743](https://github.com/airbnb/caravel/commit/19677438c23a9beab907b5b51d99f54ef62c8f92) Add cascade delete to the 1 to composite relationships. (#1295) (@bkyryliuk)
- [9012b11](https://github.com/airbnb/caravel/commit/9012b11101805c9810745f049363223f110bc93e) add ImmutableMultiDict back to views.py (#1298) (@ascott)
- [f70d301](https://github.com/airbnb/caravel/commit/f70d301f0d37fe6c4f94cd7d6026a72a56087d34) Refactor the explore view (#1252) (@mistercrunch)
- [b7d1f78](https://github.com/airbnb/caravel/commit/b7d1f78f5e38bdcc99c7b6a15645092f5d76ca4a) Put formData in store (#1281) (@vera-liu)
- [3384e75](https://github.com/airbnb/caravel/commit/3384e7598ee9e82f8b83ae71e3e5b587c6546443) Fixing explore actions & slice controller interactions (#1292) (@mistercrunch)
- [382b8e8](https://github.com/airbnb/caravel/commit/382b8e85da36ed1a8f235775b883e54f5db90ab7) [explore v2] add scrollbar to control panel container (#1284) (@ascott)
- [0a3121c](https://github.com/airbnb/caravel/commit/0a3121c2438f74ab1bd3730eac7a11bad0b317f5) [doc] installation, load examples before init (@mistercrunch)
- [ecfe1a2](https://github.com/airbnb/caravel/commit/ecfe1a241786bc1fae1d5d3c45b45e21703e33a7) Updated eslinter for object rest spread (#1289) (@vera-liu)
- [609ae22](https://github.com/airbnb/caravel/commit/609ae22bdabfb9a9cb99d1a4bfba62367f03a8d5) less number of default workers. (#1206) (@StefanoOrdine)
- [94578cb](https://github.com/airbnb/caravel/commit/94578cb6a7e91cb4ca741a8f437636d264b56322) reduce chunk size for countries table (#1279) (@vivo75)
- [8a5f050](https://github.com/airbnb/caravel/commit/8a5f050f6cbf2a4eca7f2799a244f94218bb11c1) [explore v2] fix explorev2 chart errors (#1277) (@ascott)
- [5c5b393](https://github.com/airbnb/caravel/commit/5c5b393f2fd7be5a4496c0ea0a0808f720fdc904) Change userId, dbId to username and dbname (#1274) (@vera-liu)
- [f837733](https://github.com/airbnb/caravel/commit/f837733d858643152304469c899c096e31d2bf24) [explorev2] chart and controls (#1251) (@ascott)
- [66b498d](https://github.com/airbnb/caravel/commit/66b498de25b6bb3145eb441f64ef7fdaffc5a747) Added controls for Table Viz (#1253) (@vera-liu)
- [659bf6d](https://github.com/airbnb/caravel/commit/659bf6d7e80d70def5b6c46a9d8a3a262e37a13e) Moved time column and grains to models.py (#1255) (@vera-liu)
- [a8a1690](https://github.com/airbnb/caravel/commit/a8a16900e7497083f14de3b6dc50063f845401b7) docs: add libsasl as system requirement on linux (#1257) (@xrmx)
- [e50b59e](https://github.com/airbnb/caravel/commit/e50b59e5535bc653e3321a2630287540ef99df86) docs: document that gunicorn does not work on windows (#1258) (@xrmx)
- [231804e](https://github.com/airbnb/caravel/commit/231804e2b47771ed6b31cb48e36c2f417973cad1) CHANGELOG: Add proper credit to tan31989 for #744 (#1259) (@xrmx)
- [421a86a](https://github.com/airbnb/caravel/commit/421a86ade5ac5ec4d147bdfb913ce32a7004b455) Some polish on query search (#1222) (@vera-liu)
- [140a055](https://github.com/airbnb/caravel/commit/140a055e4ef85080bbe3e7defdfeb2dd7b828b58) [docs] add line in installation instructions (@mistercrunch)
- [5bf86d9](https://github.com/airbnb/caravel/commit/5bf86d91ec9911e6155335ff1f97dc48c2c16a21) [docs] suggest to upgrade pip and setuptools (@mistercrunch)
- [715cdd9](https://github.com/airbnb/caravel/commit/715cdd98fb213e06c687ee8587ded9437039fb2d) Changelog for 0.11.0 (@mistercrunch)
### 0.11.0 (2016/10/05 04:27 +00:00)
- [7a01d9d](https://github.com/airbnb/caravel/commit/7a01d9dbcbbd7678960c33c8cca1b13680290ac7) v0.11.0 (@mistercrunch)
- [58dfa43](https://github.com/airbnb/caravel/commit/58dfa436ee53aac185b457e721bfe2303b8d006a) Do not shadow _ function. (#1254) (@bkyryliuk)
+29 -29
View File
@@ -30,8 +30,8 @@ Look through the GitHub issues for features. Anything tagged with
### Documentation
Caravel could always use better documentation,
whether as part of the official Caravel docs,
Superset could always use better documentation,
whether as part of the official Superset docs,
in docstrings, `docs/*.rst` or even on the web as blog posts or
articles.
@@ -49,16 +49,16 @@ If you are proposing a feature:
## Latest Documentation
Latest documentation and tutorial are available [here](http://airbnb.io/caravel)
Latest documentation and tutorial are available [here](http://airbnb.io/superset)
## Setting up a Python development environment
Check the [OS dependencies](http://airbnb.io/caravel/installation.html#os-dependencies) before follows these steps.
Check the [OS dependencies](http://airbnb.io/superset/installation.html#os-dependencies) before follows these steps.
# fork the repo on GitHub and then clone it
# alternatively you may want to clone the main repo but that won't work
# so well if you are planning on sending PRs
# git clone git@github.com:airbnb/caravel.git
# git clone git@github.com:airbnb/superset.git
# [optional] setup a virtual env and activate it
virtualenv env
@@ -68,24 +68,24 @@ Check the [OS dependencies](http://airbnb.io/caravel/installation.html#os-depend
python setup.py develop
# Create an admin user
fabmanager create-admin --app caravel
fabmanager create-admin --app superset
# Initialize the database
caravel db upgrade
superset db upgrade
# Create default roles and permissions
caravel init
superset init
# Load some data to play with
caravel load_examples
superset load_examples
# start a dev web server
caravel runserver -d
superset runserver -d
## Setting up the node / npm javascript environment
`caravel/assets` contains all npm-managed, front end assets.
`superset/assets` contains all npm-managed, front end assets.
Flask-Appbuilder itself comes bundled with jQuery and bootstrap.
While these may be phased out over time, these packages are currently not
managed with npm.
@@ -112,14 +112,14 @@ export PATH="$HOME/.npm-packages/bin:$PATH"
#### npm packages
To install third party libraries defined in `package.json`, run the
following within the `caravel/assets/` directory which will install them in a
following within the `superset/assets/` directory which will install them in a
new `node_modules/` folder within `assets/`.
```
npm install
```
To parse and generate bundled files for caravel, run either of the
To parse and generate bundled files for superset, run either of the
following commands. The `dev` flag will keep the npm script running and
re-run it upon any changes within the assets directory.
@@ -135,7 +135,7 @@ For every development session you will have to start a flask dev server
as well as an npm watcher
```
caravel runserver -d -p 8081
superset runserver -d -p 8081
npm run dev
```
@@ -147,7 +147,7 @@ Python tests can be run with:
We use [Mocha](https://mochajs.org/), [Chai](http://chaijs.com/) and [Enzyme](http://airbnb.io/enzyme/) to test Javascript. Tests can be run with:
cd /caravel/caravel/assets/javascripts
cd /superset/superset/assets/javascripts
npm i
npm run test
@@ -157,13 +157,13 @@ Lint the project with:
# for python changes
flake8 changes tests
flake8 changes caravel
flake8 changes superset
# for javascript
npm run lint
## Linting with codeclimate
Codeclimate is a service we use to measure code quality and test coverage. To get codeclimate's report on your branch, ideally before sending your PR, you can setup codeclimate against your Caravel fork. After you push to your fork, you should be able to get the report at http://codeclimate.com . Alternatively, if you prefer to work locally, you can install the codeclimate cli tool.
Codeclimate is a service we use to measure code quality and test coverage. To get codeclimate's report on your branch, ideally before sending your PR, you can setup codeclimate against your Superset fork. After you push to your fork, you should be able to get the report at http://codeclimate.com . Alternatively, if you prefer to work locally, you can install the codeclimate cli tool.
*Install the codeclimate cli tool*
```
@@ -193,12 +193,12 @@ Generate the documentation with:
cd docs && ./build.sh
## CSS Themes
As part of the npm build process, CSS for Caravel is compiled from `Less`, a dynamic stylesheet language.
As part of the npm build process, CSS for Superset is compiled from `Less`, a dynamic stylesheet language.
It's possible to customize or add your own theme to Caravel, either by overriding CSS rules or preferably
It's possible to customize or add your own theme to Superset, either by overriding CSS rules or preferably
by modifying the Less variables or files in `assets/stylesheets/less/`.
The `variables.less` and `bootswatch.less` files that ship with Caravel are derived from
The `variables.less` and `bootswatch.less` files that ship with Superset are derived from
[Bootswatch](https://bootswatch.com) and thus extend Bootstrap. Modify variables in these files directly, or
swap them out entirely with the equivalent files from other Bootswatch (themes)[https://github.com/thomaspark/bootswatch.git]
@@ -221,14 +221,14 @@ meets these guidelines:
## Translations
We use [Babel](http://babel.pocoo.org/en/latest/) to translate Caravel. The
We use [Babel](http://babel.pocoo.org/en/latest/) to translate Superset. The
key is to instrument the strings that need translation using
`from flask_babel import lazy_gettext as _`. Once this is imported in
a module, all you have to do is to `_("Wrap your strings")` using the
underscore `_` "function".
To enable changing language in your environment, you can simply add the
`LANGUAGES` parameter to your `caravel_config.py`. Having more than one
`LANGUAGES` parameter to your `superset_config.py`. Having more than one
options here will add a language selection dropdown on the right side of the
navigation bar.
@@ -241,23 +241,23 @@ navigation bar.
As per the [Flask AppBuilder documentation] about translation, to create a
new language dictionary, run the following command:
pybabel init -i ./babel/messages.pot -d caravel/translations -l es
pybabel init -i ./babel/messages.pot -d superset/translations -l es
Then it's a matter of running the statement below to gather all stings that
need translation
fabmanager babel-extract --target caravel/translations/
fabmanager babel-extract --target superset/translations/
You can then translate the strings gathered in files located under
`caravel/translation`, where there's one per language. For the translations
`superset/translation`, where there's one per language. For the translations
to take effect, they need to be compiled using this command:
fabmanager babel-compile --target caravel/translations/
fabmanager babel-compile --target superset/translations/
## Adding new datasources
1. Create Models and Views for the datasource, add them under caravel folder, like a new my_models.py
1. Create Models and Views for the datasource, add them under superset folder, like a new my_models.py
with models for cluster, datasources, columns and metrics and my_views.py with clustermodelview
and datasourcemodelview.
@@ -267,6 +267,6 @@ to take effect, they need to be compiled using this command:
For example:
`ADDITIONAL_MODULE_DS_MAP = {'caravel.my_models': ['MyDatasource', 'MyOtherDatasource']}`
`ADDITIONAL_MODULE_DS_MAP = {'superset.my_models': ['MyDatasource', 'MyOtherDatasource']}`
This means it'll register MyDatasource and MyOtherDatasource in caravel.my_models module in the source registry.
This means it'll register MyDatasource and MyOtherDatasource in superset.my_models module in the source registry.
+2 -1
View File
@@ -1,4 +1,4 @@
Please use [pull requests](https://github.com/airbnb/caravel/pull/new/master)
Please use [pull requests](https://github.com/airbnb/superset/pull/new/master)
to add your organization and/or project to this document!
Organizations
@@ -8,6 +8,7 @@ Organizations
- [Maieutical Labs] (https://cloudschooling.it)
- [Shopkick] (https://www.shopkick.com)
- [Amino] (https://amino.com)
- [Faasos] (http://faasos.com/)
Projects
----------
+3 -3
View File
@@ -1,11 +1,11 @@
Make sure these boxes are checked before submitting your issue - thank you!
- [ ] I have checked the caravel logs for python stacktraces and included it here as text if any
- [ ] I have reproduced the issue with at least the latest released version of caravel
- [ ] I have checked the superset logs for python stacktraces and included it here as text if any
- [ ] I have reproduced the issue with at least the latest released version of superset
- [ ] I have checked the issue tracker for the same issue and I haven't found one similar
### Caravel version
### Superset version
### Expected results
+8 -8
View File
@@ -1,9 +1,9 @@
recursive-include caravel/templates *
recursive-include caravel/static *
recursive-exclude caravel/static/assets/node_modules *
recursive-include caravel/static/assets/node_modules/font-awesome *
recursive-exclude caravel/static/docs *
recursive-exclude caravel/static/spec *
recursive-include superset/templates *
recursive-include superset/static *
recursive-exclude superset/static/assets/node_modules *
recursive-include superset/static/assets/node_modules/font-awesome *
recursive-exclude superset/static/docs *
recursive-exclude superset/static/spec *
recursive-exclude tests *
recursive-include caravel/data *
recursive-include caravel/migrations *
recursive-include superset/data *
recursive-include superset/migrations *
+49 -50
View File
@@ -1,47 +1,51 @@
Caravel
Superset
=========
<img src="http://i.imgur.com/H0Kyvyi.jpg" style="border-radius: 20px; box-shadow:5px 5px 5px gray;" alt="Caravel" width="500"/>
[![Build Status](https://travis-ci.org/airbnb/caravel.svg?branch=master)](https://travis-ci.org/airbnb/caravel)
[![PyPI version](https://badge.fury.io/py/caravel.svg)](https://badge.fury.io/py/caravel)
[![Coverage Status](https://coveralls.io/repos/airbnb/caravel/badge.svg?branch=master&service=github)](https://coveralls.io/github/airbnb/caravel?branch=master)
[![JS Test Coverage](https://codeclimate.com/github/airbnb/caravel/badges/coverage.svg)](https://codeclimate.com/github/airbnb/caravel/coverage)
[![Code Health](https://landscape.io/github/airbnb/caravel/master/landscape.svg?style=flat)](https://landscape.io/github/airbnb/caravel/master)
[![Code Climate](https://codeclimate.com/github/airbnb/caravel/badges/gpa.svg)](https://codeclimate.com/github/airbnb/caravel)
[![PyPI](https://img.shields.io/pypi/pyversions/caravel.svg?maxAge=2592000)](https://pypi.python.org/pypi/caravel)
[![Requirements Status](https://requires.io/github/airbnb/caravel/requirements.svg?branch=master)](https://requires.io/github/airbnb/caravel/requirements/?branch=master)
[![Join the chat at https://gitter.im/airbnb/caravel](https://badges.gitter.im/airbnb/caravel.svg)](https://gitter.im/airbnb/caravel?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Documentation](https://img.shields.io/badge/docs-airbnb.io-blue.svg)](http://airbnb.io/caravel/)
[![dependencies Status](https://david-dm.org/airbnb/caravel/status.svg?path=caravel/assets)](https://david-dm.org/airbnb/caravel?path=caravel/assets)
[![Build Status](https://travis-ci.org/airbnb/superset.svg?branch=master)](https://travis-ci.org/airbnb/superset)
[![PyPI version](https://badge.fury.io/py/superset.svg)](https://badge.fury.io/py/superset)
[![Coverage Status](https://coveralls.io/repos/airbnb/superset/badge.svg?branch=master&service=github)](https://coveralls.io/github/airbnb/superset?branch=master)
[![JS Test Coverage](https://codeclimate.com/github/airbnb/superset/badges/coverage.svg)](https://codeclimate.com/github/airbnb/superset/coverage)
[![Code Health](https://landscape.io/github/airbnb/superset/master/landscape.svg?style=flat)](https://landscape.io/github/airbnb/superset/master)
[![Code Climate](https://codeclimate.com/github/airbnb/superset/badges/gpa.svg)](https://codeclimate.com/github/airbnb/superset)
[![PyPI](https://img.shields.io/pypi/pyversions/superset.svg?maxAge=2592000)](https://pypi.python.org/pypi/superset)
[![Requirements Status](https://requires.io/github/airbnb/superset/requirements.svg?branch=master)](https://requires.io/github/airbnb/superset/requirements/?branch=master)
[![Join the chat at https://gitter.im/airbnb/superset](https://badges.gitter.im/airbnb/superset.svg)](https://gitter.im/airbnb/superset?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Documentation](https://img.shields.io/badge/docs-airbnb.io-blue.svg)](http://airbnb.io/superset/)
[![dependencies Status](https://david-dm.org/airbnb/superset/status.svg?path=superset/assets)](https://david-dm.org/airbnb/superset?path=superset/assets)
Caravel is a data exploration platform designed to be visual, intuitive
**Superset** is a data exploration platform designed to be visual, intuitive
and interactive.
[this project used to be named **Panoramix**]
[this project used to be named **Caravel**, and **Panoramix** in the past]
Screenshots & Gifs
------------------
![img](http://g.recordit.co/xFXSvaGUts.gif)
---
![img](http://g.recordit.co/uZggYOdR5g.gif)
**View Dashboards**
![superset-dashboard](https://cloud.githubusercontent.com/assets/130878/20371438/a703a2a0-ac19-11e6-80c4-00a47c2eb644.gif)
---
![img](http://g.recordit.co/U70FWLpLvh.gif)
<br/>
**View/Edit a Slice**
![superset-explore-slice](https://cloud.githubusercontent.com/assets/130878/20372732/410392f4-ac22-11e6-9c6d-3ef512e81212.gif)
---
![img](http://i.imgur.com/x8t30YU.png)
<br/>
**Query and Visualize with SQL Lab**
![superset-sql-lab-visualization](https://cloud.githubusercontent.com/assets/130878/20372911/7c3b3358-ac23-11e6-8f24-923ef1b35715.gif)
---
![img](http://i.imgur.com/DRCnbq6.png)
<br/>
![superset-dashboard-misc](https://cloud.githubusercontent.com/assets/130878/20234704/0f40778c-a835-11e6-9556-983a62ea061b.png)
Caravel
![superset-edit-table](https://cloud.githubusercontent.com/assets/130878/20234705/0f415c88-a835-11e6-8b03-f7c35d56dd7d.png)
![superset-query-search](https://cloud.githubusercontent.com/assets/130878/20234706/0f430a10-a835-11e6-8a0d-8b26cc2e6bbd.png)
Superset
---------
Caravel's main goal is to make it easy to slice, dice and visualize data.
Superset's main goal is to make it easy to slice, dice and visualize data.
It empowers users to perform **analytics at the speed of thought**.
Caravel provides:
Superset provides:
* A quick way to intuitively visualize datasets by allowing users to create
and share interactive dashboards
* A rich set of visualizations to analyze your data, as well as a flexible
@@ -54,7 +58,7 @@ Caravel provides:
displayed in the UI, by defining which fields should show up in
which dropdown and which aggregation and function (metrics) are
made available to the user
* Deep integration with Druid allows for Caravel to stay blazing fast while
* Deep integration with Druid allows for Superset to stay blazing fast while
slicing and dicing large, realtime datasets
* Fast loading dashboards with configurable caching
@@ -62,7 +66,7 @@ Caravel provides:
Database Support
----------------
Caravel was originally designed on top of Druid.io, but quickly broadened
Superset was originally designed on top of Druid.io, but quickly broadened
its scope to support other databases through the use of SQLAlchemy, a Python
ORM that is compatible with
[most common databases](http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html).
@@ -83,55 +87,50 @@ power analytic dashboards and applications.*
Installation & Configuration
----------------------------
[See in the documentation](http://airbnb.io/caravel/installation.html)
[See in the documentation](http://airbnb.io/superset/installation.html)
More screenshots
----------------
![img](http://i.imgur.com/SAhDJCI.png)
![superset-security-menu](https://cloud.githubusercontent.com/assets/130878/20234707/0f565886-a835-11e6-9277-b4f5f4aa2fcc.png)
---
![img](http://i.imgur.com/iuLpv1c.png)
![superset-slice-bubble](https://cloud.githubusercontent.com/assets/130878/20234708/0f57f3d0-a835-11e6-8268-fcefe8f868c8.png)
---
![img](http://i.imgur.com/V2FWeZx.png)
![superset-slice-map](https://cloud.githubusercontent.com/assets/130878/20234709/0f5a5a44-a835-11e6-987a-1b6f8ac9922b.png)
---
![img](http://i.imgur.com/BeUtCzF.png)
![superset-slice-multiline](https://cloud.githubusercontent.com/assets/130878/20234710/0f632d68-a835-11e6-98d1-542dcb618193.png)
---
![img](http://i.imgur.com/phoY7jI.png)
![superset-slice-sankey](https://cloud.githubusercontent.com/assets/130878/20234711/0f639136-a835-11e6-8721-fe5e48dab8e7.png)
---
![img](http://i.imgur.com/NvIDgdC.png)
![superset-slice-view](https://cloud.githubusercontent.com/assets/130878/20234712/0f63c4c6-a835-11e6-8595-6091a6428fa9.png)
---
![img](http://i.imgur.com/DzwYyns.png)
![superset-sql-lab-2](https://cloud.githubusercontent.com/assets/130878/20234713/0f67b856-a835-11e6-9d50-7a52168f66fd.png)
![superset-sql-lab](https://cloud.githubusercontent.com/assets/130878/20234714/0f68f45a-a835-11e6-9467-f47ad0af7e79.png)
Resources
-------------
* [Caravel Google Group](https://groups.google.com/forum/#!forum/airbnb_caravel)
* [Gitter (live chat) Channel](https://gitter.im/airbnb/caravel)
* [Docker image 1](https://hub.docker.com/r/kochalex/caravel/)
[Docker image 2](https://hub.docker.com/r/amancevice/caravel/) (community contributed)
* [Superset Google Group](https://groups.google.com/forum/#!forum/airbnb_superset)
* [Gitter (live chat) Channel](https://gitter.im/airbnb/superset)
* [Docker image](https://hub.docker.com/r/amancevice/superset/) (community contributed)
* [Slides from Strata (March 2016)](https://drive.google.com/open?id=0B5PVE0gzO81oOVJkdF9aNkJMSmM)
Tip of the Hat
--------------
Caravel would not be possible without these great frameworks / libs
Superset would not be possible without these great frameworks / libs
* Flask App Builder - Allowing us to focus on building the app quickly while
getting the foundation for free
* The Flask ecosystem - Simply amazing. So much Plug, easy play.
* NVD3 - One of the best charting libraries out there
* Much more, check out the `install_requires` section in the [setup.py](https://github.com/airbnb/caravel/blob/master/setup.py) file!
* Much more, check out the `install_requires` section in the [setup.py](https://github.com/airbnb/superset/blob/master/setup.py) file!
Contributing
------------
Interested in contributing? Casual hacking? Check out [Contributing.MD](https://github.com/airbnb/caravel/blob/master/CONTRIBUTING.md)
Interested in contributing? Casual hacking? Check out [Contributing.MD](https://github.com/airbnb/superset/blob/master/CONTRIBUTING.md)
+2 -2
View File
@@ -1,5 +1,5 @@
# TODO
List of TODO items for Caravel
List of TODO items for Superset
## Important
* **Getting proper JS testing:** unit tests on the Python side are pretty
@@ -7,7 +7,7 @@ List of TODO items for Caravel
testing all the ajax-type calls
* **Viz Plugins:** Allow people to define and share visualization plugins.
ideally one would only need to drop in a set of files in a folder and
Caravel would discover and expose the plugins
Superset would discover and expose the plugins
## Features
* **Dashboard URL filters:** `{dash_url}#fltin__fieldname__value1,value2`
+1 -1
View File
@@ -29,7 +29,7 @@ script_location = migrations
# are written from script.py.mako
# output_encoding = utf-8
sqlalchemy.url = scheme://localhost/caravel
sqlalchemy.url = scheme://localhost/superset
# Logging configuration
[loggers]
+3 -3
View File
@@ -1,4 +1,4 @@
[ignore: caravel/assets/node_modules/**]
[python: caravel/**.py]
[jinja2: caravel/**/templates/**.html]
[ignore: superset/assets/node_modules/**]
[python: superset/**.py]
[jinja2: superset/**/templates/**.html]
encoding = utf-8
+439 -439
View File
File diff suppressed because it is too large Load Diff
-82
View File
@@ -1,82 +0,0 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
error = (
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM8OI++=~~~~~~=+?IODMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMMMMD$~~~~~~~~~~~~~~~~~~~~~~~=$MMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMN8?:~~~~~~~~~~~~~~~~~~~~~~~~~~=+8NMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMO=~~~~~~~~~~~~~~~~~+I??~~~~~~~~~~~~~+DMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMNI~~~~~~~~~~~~~~~~~~IIIII=~~~~~~~~~~~~~~=NMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMM+=~~~~~~~~~~~~~~~~~~~=III+~~~~~~~~~~~~~~~~~?8MMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMM?~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+++=~~~~8MMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMI=~~~~~~~~~~~~~~~~~~~~~~~~~III?I~~~~~~~~,:++++++~~8MMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMN7~~~~~~~~~~~~~~~~==+=~~~~~~=IIIII~~~~~~:. ..:=++=~=MMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMO=~~~~~~~~~~~~~~~~+++=~~~~~~~~??I?I~~~~~~. ...,~~~~IMMMMMMMMMMMMM\n"+
"MMMMMMMMMMM~~~~~~~~~~~~~~~~~+++:,~~~~~~~~~~~?=~~~~~:. ..~~~~~OMMMMMMMMMMMM\n"+
"MMMMMMMMM$=~~~~~~~~~~~~~~~=++:.. ..~~~~~~~~~~~~~~~~,. . . :~~~~~OMMMMMMMMMMM\n"+
"MMMMMMMMM~~~~~~~~~~~~~~~~+++,. .~~~~~~~~~~~~~~~.. .. . .~~~~~=OMMMMMMMMMM\n"+
"MMMMMMMM?~~~~~~~~~~~~~~~=+~. .~~~~~~~~~~~~~~. ,MMMMM,=~~~~~~NMMMMMMMMM\n"+
"MMMMMMMN~~~~~~~~~~~~~~~~~,. .,~~~~~~~~~~~~~.. ZMMM,+Z:~~~~~~$MMMMMMMMM\n"+
"MMMMMM8?~~~~~~~~~~~~~~~~~.. ..~~~~~~~~~~~~~:. DMMM,+D~~~~~~~~IMMMMMMMM\n"+
"MMMMMMI~~~~~~~~~~~~~~~~~~.. :MMMO~~~~~~~~~~~~~~~,.. ?MMMMMI~~~~~~~~~MMMMMMMM\n"+
"MMMMMM=~~~~~~~~~~~~~~~~~~.. MMM+=M:~~~~~~~~~~~~~:. .:IM$~~~~~~~~~~~8MMMMMMM\n"+
"MMMMMD~~~~~~~~~~~~~~~~~~~:. MMM:,M:~~~~~~~~~~~~~~~.......:~~~~~~~~~~$MMMMMMM\n"+
"MMMMMI~~~~~~~~~~~~~~~~~~~~, MMMMMM~~~~~~~~~~~~~~~~~~,..:~~~~~~~~~~~~+MMMMMMM\n"+
"MMMMD+~~~~~~~~~~~~~~~~~~~~~. $MMMM$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=MMMMMMM\n"+
"MMMM8~~~~~~~~~~~~~~~~~~~~~~:. . .:~~~~~~,..:. .=~~~~~~~~~~~~~~~~~~~~MMMMMMM\n"+
"MMMMO~~~~~~~~~~~~~~~~~~~~~~~:, .:~~~~~=8.. .+ . =8ZI~~~~~~~~~~~~~~~~=MMMMMMM\n"+
"MMMMZ=~~~~~~~~~~~~~~~~~~~~~~~~:,,,:~~~~~~IZ8:. .O....888?~~~~~~~~~~~~~~~+MMMMMMM\n"+
"MMMMO=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~?888=...I~I88888O?~~~~~~~~~~~~~~7MMMMMMM\n"+
"MMMMO~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Z888OO88888888888O?~~~~~~~~~~~~~OMMMMMMM\n"+
"MMMMD+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=8888888888888888888~~~~~~~~~~~~+MMMMMMMM\n"+
"MMMMM7~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~?8888888888888888888?~~~~~~~~~~=$MMMMMMMM\n"+
"MMMMMD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=$8888888888888888888O~~~~~~~~~~8MMMMMMMMM\n"+
"MMMMMN=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Z88888888888888888ZZ7=~~~~~~~~?MMMMMMMMMM\n"+
"MMMMMMZ=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Z88888888Z7I===~~~~~~~~~~~~~=OMMMMMMMMMMM\n"+
"MMMMMMN$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=$88888O7?=~~~~~~~~~~~~~~~~~~OMMMMMMMMMMMM\n"+
"MMMMMMMM?~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~I8OZ+~~~~~~~~~~~~~~~~~~~~=DMMMMMMMMMMMMMM\n"+
"MMMMMMMM8=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+$+=~~~~~~~~~~~~~~~~~~~~+MMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMD7~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=$DMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMM?~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=$OMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMD7=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ZMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMZ7=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~78MMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMM8OI=~~~~~~~~~~~~~~~~~~~=+?ZDNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMNDZ7?++~=~==~+?IONMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n"+
"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM")
stacktrace="""
-------------------------------------------------------------------------------------------------------
=======================================================================================================
-------------------------------------------------------------------------------------------------------
___ ___ ___
( ) ( ) ( )
.--. | |_ .---. .--. | | ___ | |_ ___ .-. .---. .--. .--.
/ _ \ ( __) / .-, \ / \ | | ( ) ( __) ( ) \ / .-, \ / \ / \\
. .' `. ; | | (__) ; | | .-. ; | | ' / | | | ' .-. ; (__) ; | | .-. ; | .-. ;
| ' | | | | ___ .'` | | |(___) | |,' / | | ___ | / (___) .'` | | |(___) | | | |
_\_`.(___) | |( ) / .'| | | | | . '. | |( ) | | / .'| | | | | |/ |
( ). '. | | | | | / | | | | ___ | | `. \ | | | | | | | / | | | | ___ | ' _.'
| | `\ | | ' | | ; | ; | | '( ) | | \ \ | ' | | | | ; | ; | | '( ) | .'.-.
; '._,' ' ' `-' ; ' `-' | ' `-' | | | \ . ' `-' ; | | ' `-' | ' `-' | ' `-' /
'.___.' `.__. `.__.'_. `.__,' (___ ) (___) `.__. (___) `.__.'_. `.__,' `.__.'
-------------------------------------------------------------------------------------------------------
=======================================================================================================
-------------------------------------------------------------------------------------------------------
"""
boat = """\
+ +
)`.).
)``)``) .~~
).-'.-')|)
|-).-).-'_'-/
~~~\ `o-o-o' /~~~~
~~~'---.____/~~~"""
-3
View File
@@ -1,3 +0,0 @@
{
"presets" : ["airbnb", "es2015", "react"]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

@@ -1,10 +0,0 @@
export const STATE_BSSTYLE_MAP = {
failed: 'danger',
pending: 'info',
fetching: 'info',
running: 'warning',
stopped: 'danger',
success: 'success',
};
export const STATUS_OPTIONS = ['success', 'failed', 'running'];
@@ -1,51 +0,0 @@
import React from 'react';
import AceEditor from 'react-ace';
import 'brace/mode/sql';
import 'brace/theme/github';
import 'brace/ext/language_tools';
const propTypes = {
sql: React.PropTypes.string.isRequired,
onBlur: React.PropTypes.func,
};
const defaultProps = {
onBlur: () => {},
};
class AceEditorWrapper extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
sql: props.sql,
};
}
textChange(text) {
this.setState({ sql: text });
}
onBlur() {
this.props.onBlur(this.state.sql);
}
render() {
return (
<AceEditor
mode="sql"
theme="github"
onBlur={this.onBlur.bind(this)}
minLines={8}
maxLines={30}
onChange={this.textChange.bind(this)}
height="200px"
width="100%"
editorProps={{ $blockScrolling: true }}
enableBasicAutocompletion
value={this.state.sql}
/>
);
}
}
AceEditorWrapper.defaultProps = defaultProps;
AceEditorWrapper.propTypes = propTypes;
export default AceEditorWrapper;
@@ -1,146 +0,0 @@
const $ = window.$ = require('jquery');
import React from 'react';
import { Button } from 'react-bootstrap';
import Select from 'react-select';
import QueryTable from './QueryTable';
import DatabaseSelect from './DatabaseSelect';
import { STATUS_OPTIONS } from '../common';
const propTypes = {
actions: React.PropTypes.object.isRequired,
};
class QuerySearch extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
userLoading: false,
userOptions: [],
databaseId: null,
userId: null,
searchText: null,
status: 'success',
queriesArray: [],
};
}
componentWillMount() {
this.fetchUsers();
this.refreshQueries();
}
onUserClicked(userId) {
this.setState({ userId }, () => { this.refreshQueries(); });
}
onDbClicked(dbId) {
this.setState({ databaseId: dbId }, () => { this.refreshQueries(); });
}
onChange(db) {
const val = (db) ? db.value : null;
this.setState({ databaseId: val });
}
insertParams(baseUrl, params) {
return baseUrl + '?' + params.join('&');
}
changeUser(user) {
const val = (user) ? user.value : null;
this.setState({ userId: val });
}
changeStatus(status) {
const val = (status) ? status.value : null;
this.setState({ status: val });
}
changeSearch(event) {
this.setState({ searchText: event.target.value });
}
fetchUsers() {
this.setState({ userLoading: true });
const url = '/users/api/read';
$.getJSON(url, (data, status) => {
if (status === 'success') {
const options = [];
for (let i = 0; i < data.pks.length; i++) {
options.push({ value: data.pks[i], label: data.result[i].username });
}
this.setState({ userOptions: options, userLoading: false });
}
});
}
refreshQueries() {
const params = [
`userId=${this.state.userId}`,
`databaseId=${this.state.databaseId}`,
`searchText=${this.state.searchText}`,
`status=${this.state.status}`,
];
const url = this.insertParams('/caravel/search_queries', params);
$.getJSON(url, (data, status) => {
if (status === 'success') {
const newQueriesArray = [];
for (const id in data) {
newQueriesArray.push(data[id]);
}
this.setState({ queriesArray: newQueriesArray });
}
});
}
render() {
return (
<div>
<div className="row space-1">
<div className="col-sm-2">
<Select
name="select-user"
placeholder="[User]"
options={this.state.userOptions}
value={this.state.userId}
isLoading={this.state.userLoading}
autosize={false}
onChange={this.changeUser.bind(this)}
/>
</div>
<div className="col-sm-2">
<DatabaseSelect
onChange={this.onChange.bind(this)}
databaseId={this.state.databaseId}
/>
</div>
<div className="col-sm-4">
<input
type="text"
onChange={this.changeSearch.bind(this)}
className="form-control input-sm"
placeholder="Search Results"
/>
</div>
<div className="col-sm-2">
<Select
name="select-state"
placeholder="[Query Status]"
options={STATUS_OPTIONS.map((s) => ({ value: s, label: s }))}
value={this.state.status}
isLoading={false}
autosize={false}
onChange={this.changeStatus.bind(this)}
/>
</div>
<Button bsSize="small" bsStyle="success" onClick={this.refreshQueries.bind(this)}>
Search
</Button>
</div>
<QueryTable
columns={[
'state', 'db', 'user',
'progress', 'rows', 'sql', 'querylink',
]}
onUserClicked={this.onUserClicked.bind(this)}
onDbClicked={this.onDbClicked.bind(this)}
queries={this.state.queriesArray}
actions={this.props.actions}
/>
</div>
);
}
}
QuerySearch.propTypes = propTypes;
export default QuerySearch;
@@ -1,50 +0,0 @@
import { Alert, Tab, Tabs } from 'react-bootstrap';
import QueryHistory from './QueryHistory';
import ResultSet from './ResultSet';
import { areArraysShallowEqual } from '../../reduxUtils';
import React from 'react';
import shortid from 'shortid';
const propTypes = {
queries: React.PropTypes.array.isRequired,
actions: React.PropTypes.object.isRequired,
};
class SouthPane extends React.PureComponent {
shouldComponentUpdate(nextProps) {
return !areArraysShallowEqual(this.props.queries, nextProps.queries);
}
render() {
let latestQuery;
const props = this.props;
if (props.queries.length > 0) {
latestQuery = props.queries[props.queries.length - 1];
}
let results;
if (latestQuery) {
results = (
<ResultSet showControls search query={latestQuery} actions={props.actions} />
);
} else {
results = <Alert bsStyle="info">Run a query to display results here</Alert>;
}
return (
<div className="SouthPane">
<Tabs bsStyle="tabs" id={shortid.generate()}>
<Tab title="Results" eventKey={1}>
<div style={{ overflow: 'auto' }}>
{results}
</div>
</Tab>
<Tab title="Query History" eventKey={2}>
<QueryHistory queries={props.queries} actions={props.actions} />
</Tab>
</Tabs>
</div>
);
}
}
SouthPane.propTypes = propTypes;
export default SouthPane;
@@ -1,226 +0,0 @@
import React from 'react';
import { ButtonGroup, Well } from 'react-bootstrap';
import shortid from 'shortid';
import CopyToClipboard from '../../components/CopyToClipboard';
import Link from './Link';
import ModalTrigger from '../../components/ModalTrigger';
const propTypes = {
table: React.PropTypes.object,
actions: React.PropTypes.object,
};
const defaultProps = {
table: null,
actions: {},
};
class TableElement extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
sortColumns: false,
};
}
popSelectStar() {
const qe = {
id: shortid.generate(),
title: this.props.table.name,
dbId: this.props.table.dbId,
autorun: true,
sql: this.props.table.selectStar,
};
this.props.actions.addQueryEditor(qe);
}
collapseTable(e) {
e.preventDefault();
this.props.actions.collapseTable(this.props.table);
}
expandTable(e) {
e.preventDefault();
this.props.actions.expandTable(this.props.table);
}
removeTable() {
this.props.actions.removeTable(this.props.table);
}
dataPreviewModal() {
const query = {
dbId: this.props.table.dbId,
sql: this.props.table.selectStar,
tableName: this.props.table.name,
sqlEditorId: null,
tab: '',
runAsync: false,
ctas: false,
};
this.props.actions.runQuery(query);
}
toggleSortColumns() {
this.setState({ sortColumns: !this.state.sortColumns });
}
render() {
const table = this.props.table;
let metadata = null;
let buttonToggle;
let header;
if (table.partitions) {
let partitionQuery;
let partitionClipBoard;
if (table.partitions.partitionQuery) {
partitionQuery = table.partitions.partitionQuery;
const tt = 'Copy partition query to clipboard';
partitionClipBoard = (
<CopyToClipboard
text={partitionQuery}
shouldShowText={false}
tooltipText={tt}
copyNode={<i className="fa fa-clipboard" />}
/>
);
}
let latest = [];
for (const k in table.partitions.latest) {
latest.push(`${k}=${table.partitions.latest[k]}`);
}
latest = latest.join('/');
header = (
<Well bsSize="small">
<div>
<small>
latest partition: {latest}
</small> {partitionClipBoard}
</div>
</Well>
);
}
if (table.expanded) {
buttonToggle = (
<a
href="#"
onClick={(e) => { this.collapseTable(e); }}
>
<strong>{table.name}</strong>
<small className="m-l-5"><i className="fa fa-minus" /></small>
</a>
);
const cols = table.columns.slice();
if (this.state.sortColumns) {
cols.sort((a, b) => a.name.toUpperCase() > b.name.toUpperCase());
}
metadata = (
<div>
{header}
<div className="table-columns">
{cols.map((col) => {
let name = col.name;
if (col.indexed) {
name = <strong>{col.name}</strong>;
}
return (
<div className="clearfix table-column" key={shortid.generate()}>
<div className="pull-left m-l-10 col-name">
{name}
</div>
<div className="pull-right text-muted">
<small> {col.type}</small>
</div>
</div>);
})}
<hr />
</div>
</div>
);
} else {
buttonToggle = (
<a
href="#"
onClick={(e) => { this.expandTable(e); }}
>
{table.name}
<small className="m-l-5"><i className="fa fa-plus" /></small>
</a>
);
}
let keyLink;
if (table.indexes && table.indexes.length > 0) {
keyLink = (
<ModalTrigger
modalTitle={
<div>
Keys for table <strong>{table.name}</strong>
</div>
}
modalBody={
<pre>{JSON.stringify(table.indexes, null, 4)}</pre>
}
triggerNode={
<Link
className="fa fa-key pull-left m-l-2"
tooltip={`View indexes (${table.indexes.length})`}
/>
}
/>
);
}
return (
<div className="TableElement">
<div className="clearfix">
<div className="pull-left">
{buttonToggle}
</div>
<div className="pull-right">
<ButtonGroup className="ws-el-controls pull-right">
{keyLink}
<Link
className={
`fa fa-sort-${!this.state.sortColumns ? 'alpha' : 'numeric'}-asc ` +
'pull-left sort-cols m-l-2'}
onClick={this.toggleSortColumns.bind(this)}
tooltip={
!this.state.sortColumns ?
'Sort columns alphabetically' :
'Original table column order'}
href="#"
/>
<Link
className="fa fa-search-plus pull-left m-l-2"
onClick={this.dataPreviewModal.bind(this)}
tooltip="Data preview"
href="#"
/>
<CopyToClipboard
copyNode={
<a className="fa fa-clipboard pull-left m-l-2" />
}
text={table.selectStar}
shouldShowText={false}
tooltipText="Copy SELECT statement to clipboard"
/>
<Link
className="fa fa-trash pull-left m-l-2"
onClick={this.removeTable.bind(this)}
tooltip="Remove from panel"
href="#"
/>
</ButtonGroup>
</div>
</div>
<div>
{metadata}
</div>
</div>
);
}
}
TableElement.propTypes = propTypes;
TableElement.defaultProps = defaultProps;
export default TableElement;
@@ -1,42 +0,0 @@
import React, { PropTypes } from 'react';
const propTypes = {
modalId: PropTypes.string.isRequired,
title: PropTypes.string,
modalContent: PropTypes.node,
customButton: PropTypes.node,
};
function Modal({ modalId, title, modalContent, customButton }) {
return (
<div className="modal fade" id={modalId} role="dialog">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 className="modal-title">{title}</h4>
</div>
<div className="modal-body">
{modalContent}
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-default"
data-dismiss="modal"
>
Cancel
</button>
{customButton}
</div>
</div>
</div>
</div>
);
}
Modal.propTypes = propTypes;
export default Modal;
@@ -1,148 +0,0 @@
const $ = window.$ = require('jquery');
export const SET_DATASOURCE = 'SET_DATASOURCE';
export const SET_TIME_COLUMN_OPTS = 'SET_TIME_COLUMN_OPTS';
export const SET_TIME_GRAIN_OPTS = 'SET_TIME_GRAIN_OPTS';
export const SET_GROUPBY_COLUMN_OPTS = 'SET_GROUPBY_COLUMN_OPTS';
export const SET_METRICS_OPTS = 'SET_METRICS_OPTS';
export const SET_COLUMN_OPTS = 'SET_COLUMN_OPTS';
export const SET_ORDERING_OPTS = 'SET_ORDERING_OPTS';
export const TOGGLE_SEARCHBOX = 'TOGGLE_SEARCHBOX';
export const SET_FILTER_COLUMN_OPTS = 'SET_FILTER_COLUMN_OPTS';
export const ADD_FILTER = 'ADD_FILTER';
export const SET_FILTER = 'SET_FILTER';
export const REMOVE_FILTER = 'REMOVE_FILTER';
export const CHANGE_FILTER_FIELD = 'CHANGE_FILTER_FIELD';
export const CHANGE_FILTER_OP = 'CHANGE_FILTER_OP';
export const CHANGE_FILTER_VALUE = 'CHANGE_FILTER_VALUE';
export const RESET_FORM_DATA = 'RESET_FORM_DATA';
export const CLEAR_ALL_OPTS = 'CLEAR_ALL_OPTS';
export const SET_DATASOURCE_TYPE = 'SET_DATASOURCE_TYPE';
export const SET_FORM_DATA = 'SET_FORM_DATA';
export function setTimeColumnOpts(timeColumnOpts) {
return { type: SET_TIME_COLUMN_OPTS, timeColumnOpts };
}
export function setTimeGrainOpts(timeGrainOpts) {
return { type: SET_TIME_GRAIN_OPTS, timeGrainOpts };
}
export function setGroupByColumnOpts(groupByColumnOpts) {
return { type: SET_GROUPBY_COLUMN_OPTS, groupByColumnOpts };
}
export function setMetricsOpts(metricsOpts) {
return { type: SET_METRICS_OPTS, metricsOpts };
}
export function setColumnOpts(columnOpts) {
return { type: SET_COLUMN_OPTS, columnOpts };
}
export function setOrderingOpts(orderingOpts) {
return { type: SET_ORDERING_OPTS, orderingOpts };
}
export function setFilterColumnOpts(filterColumnOpts) {
return { type: SET_FILTER_COLUMN_OPTS, filterColumnOpts };
}
export function resetFormData() {
// Clear all form data when switching datasource
return { type: RESET_FORM_DATA };
}
export function clearAllOpts() {
return { type: CLEAR_ALL_OPTS };
}
export function setDatasourceType(datasourceType) {
return { type: SET_DATASOURCE_TYPE, datasourceType };
}
export function setFormOpts(datasourceId, datasourceType) {
return function (dispatch) {
const timeColumnOpts = [];
const groupByColumnOpts = [];
const metricsOpts = [];
const filterColumnOpts = [];
const timeGrainOpts = [];
const columnOpts = [];
const orderingOpts = [];
if (datasourceId) {
const params = [`datasource_id=${datasourceId}`, `datasource_type=${datasourceType}`];
const url = '/caravel/fetch_datasource_metadata?' + params.join('&');
$.get(url, (data, status) => {
if (status === 'success') {
data.time_columns.forEach((d) => {
if (d) timeColumnOpts.push({ value: d, label: d });
});
data.groupby_cols.forEach((d) => {
if (d) groupByColumnOpts.push({ value: d, label: d });
});
data.metrics.forEach((d) => {
if (d) metricsOpts.push({ value: d[1], label: d[0] });
});
data.filter_cols.forEach((d) => {
if (d) filterColumnOpts.push({ value: d, label: d });
});
data.time_grains.forEach((d) => {
if (d) timeGrainOpts.push({ value: d, label: d });
});
data.columns.forEach((d) => {
if (d) columnOpts.push({ value: d, label: d });
});
data.ordering_cols.forEach((d) => {
if (d) orderingOpts.push({ value: d, label: d });
});
// Repopulate options for controls
dispatch(setTimeColumnOpts(timeColumnOpts));
dispatch(setTimeGrainOpts(timeGrainOpts));
dispatch(setGroupByColumnOpts(groupByColumnOpts));
dispatch(setMetricsOpts(metricsOpts));
dispatch(setFilterColumnOpts(filterColumnOpts));
dispatch(setColumnOpts(columnOpts));
dispatch(setOrderingOpts(orderingOpts));
}
});
} else {
// Clear all Select options
dispatch(clearAllOpts());
}
};
}
export function setDatasource(datasourceId) {
return { type: SET_DATASOURCE, datasourceId };
}
export function toggleSearchBox(searchBox) {
return { type: TOGGLE_SEARCHBOX, searchBox };
}
export function addFilter(filter) {
return { type: ADD_FILTER, filter };
}
export function removeFilter(filter) {
return { type: REMOVE_FILTER, filter };
}
export function changeFilterField(filter, field) {
return { type: CHANGE_FILTER_FIELD, filter, field };
}
export function changeFilterOp(filter, op) {
return { type: CHANGE_FILTER_OP, filter, op };
}
export function changeFilterValue(filter, value) {
return { type: CHANGE_FILTER_VALUE, filter, value };
}
export function setFormData(key, value) {
return { type: SET_FORM_DATA, key, value };
}
@@ -1,105 +0,0 @@
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { Panel } from 'react-bootstrap';
import visMap from '../../../visualizations/main';
import { d3format } from '../../modules/utils';
const propTypes = {
sliceName: PropTypes.string.isRequired,
vizType: PropTypes.string.isRequired,
height: PropTypes.string.isRequired,
sliceContainerId: PropTypes.string.isRequired,
jsonEndpoint: PropTypes.string.isRequired,
columnFormats: PropTypes.object,
};
class ChartContainer extends React.Component {
componentDidMount() {
this.renderVis();
}
componentDidUpdate() {
this.renderVis();
}
getMockedSliceObject() {
return {
jsonEndpoint: () => this.props.jsonEndpoint,
container: {
html: () => {
// this should be a callback to clear the contents of the slice container
},
css: () => {
// dimension can be 'height'
// pixel string can be '300px'
// should call callback to adjust height of chart
},
height: () => parseInt(this.props.height, 10) - 100,
},
width: () => this.chartContainerRef.getBoundingClientRect().width,
height: () => parseInt(this.props.height, 10) - 100,
selector: `#${this.props.sliceContainerId}`,
done: () => {
// finished rendering callback
},
d3format: (col, number) => {
// mock d3format function in Slice object in caravel.js
const format = this.props.columnFormats[col];
return d3format(format, number);
},
};
}
renderVis() {
const slice = this.getMockedSliceObject();
visMap[this.props.vizType](slice).render();
}
render() {
return (
<div className="chart-container">
<Panel
style={{ height: this.props.height }}
header={
<div
id="slice-header"
className="panel-title"
>
{this.props.sliceName}
</div>
}
>
<div
id={this.props.sliceContainerId}
ref={(ref) => { this.chartContainerRef = ref; }}
className={this.props.vizType}
/>
</Panel>
</div>
);
}
}
ChartContainer.propTypes = propTypes;
function mapStateToProps(state) {
return {
sliceName: state.sliceName,
vizType: state.viz.formData.vizType,
sliceContainerId: `slice-container-${state.viz.formData.sliceId}`,
jsonEndpoint: state.viz.jsonEndPoint,
columnFormats: state.viz.columnFormats,
};
}
function mapDispatchToProps() {
return {};
}
export default connect(mapStateToProps, mapDispatchToProps)(ChartContainer);
@@ -1,89 +0,0 @@
import React from 'react';
import Select from 'react-select';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
import { VIZ_TYPES } from '../constants';
const propTypes = {
actions: React.PropTypes.object,
datasources: React.PropTypes.array,
datasourceId: React.PropTypes.number,
datasourceType: React.PropTypes.string,
vizType: React.PropTypes.string,
};
const defaultProps = {
datasources: [],
datasourceId: null,
datasourceType: null,
vizType: null,
};
class ChartControl extends React.Component {
componentWillMount() {
if (this.props.datasourceId) {
this.props.actions.setFormOpts(this.props.datasourceId, this.props.datasourceType);
}
}
changeDatasource(datasourceOpt) {
const val = (datasourceOpt) ? datasourceOpt.value : null;
this.props.actions.setDatasource(val);
this.props.actions.resetFormData();
this.props.actions.setFormOpts(val, this.props.datasourceType);
}
changeViz(opt) {
const val = opt ? opt.value : null;
this.props.actions.setFormData('vizType', val);
}
render() {
return (
<div className="panel">
<div className="panel-header">Chart Options</div>
<div className="panel-body">
<h5 className="section-heading">Datasource</h5>
<div className="row">
<Select
name="select-datasource"
placeholder="Select a datasource"
options={this.props.datasources.map((d) => ({ value: d[0], label: d[1] }))}
value={this.props.datasourceId}
autosize={false}
onChange={this.changeDatasource.bind(this)}
/>
</div>
<h5 className="section-heading">Viz Type</h5>
<div className="row">
<Select
name="select-viztype"
placeholder="Select a viz type"
options={VIZ_TYPES}
value={this.props.vizType}
autosize={false}
onChange={this.changeViz.bind(this)}
/>
</div>
</div>
</div>
);
}
}
ChartControl.propTypes = propTypes;
ChartControl.defaultProps = defaultProps;
function mapStateToProps(state) {
return {
datasources: state.datasources,
datasourceId: state.datasourceId,
datasourceType: state.datasourceType,
vizType: state.viz.formData.vizType,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ChartControl);
@@ -1,40 +0,0 @@
import React from 'react';
import { connect } from 'react-redux';
import { Panel } from 'react-bootstrap';
import { DefaultControls, VIZ_CONTROL_MAPPING } from '../constants';
const propTypes = {
vizType: React.PropTypes.string,
};
const defaultProps = {
vizType: null,
};
function ControlPanelsContainer(props) {
return (
<Panel>
<div className="scrollbar-container">
<div className="scrollbar-content">
{DefaultControls}
{VIZ_CONTROL_MAPPING[props.vizType]}
</div>
</div>
</Panel>
);
}
ControlPanelsContainer.propTypes = propTypes;
ControlPanelsContainer.defaultProps = defaultProps;
function mapStateToProps(state) {
return {
vizType: state.viz.formData.vizType,
};
}
function mapDispatchToProps() {
return {};
}
export default connect(mapStateToProps, mapDispatchToProps)(ControlPanelsContainer);
@@ -1,46 +0,0 @@
import React from 'react';
import ChartContainer from './ChartContainer';
import ControlPanelsContainer from './ControlPanelsContainer';
import QueryAndSaveBtns from '../../explore/components/QueryAndSaveBtns';
export default class ExploreViewContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
height: this.getHeight(),
};
}
getHeight() {
const navHeight = 90;
return `${window.innerHeight - navHeight}px`;
}
render() {
return (
<div
className="container-fluid"
style={{
height: this.state.height,
overflow: 'hidden',
}}
>
<div className="row">
<div className="col-sm-4">
<QueryAndSaveBtns
canAdd="True"
onQuery={() => {}}
/>
<br /><br />
<ControlPanelsContainer />
</div>
<div className="col-sm-8">
<ChartContainer
height={this.state.height}
/>
</div>
</div>
</div>
);
}
}
@@ -1,127 +0,0 @@
import React from 'react';
// import { Tab, Row, Col, Nav, NavItem } from 'react-bootstrap';
import Select from 'react-select';
import { Button } from 'react-bootstrap';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import shortid from 'shortid';
const propTypes = {
actions: React.PropTypes.object,
filterColumnOpts: React.PropTypes.array,
filters: React.PropTypes.array,
};
const defaultProps = {
filterColumnOpts: [],
filters: [],
};
class Filters extends React.Component {
constructor(props) {
super(props);
this.state = {
opOpts: ['in', 'not in'],
};
}
changeField(filter, fieldOpt) {
const val = (fieldOpt) ? fieldOpt.value : null;
this.props.actions.changeFilterField(filter, val);
}
changeOp(filter, opOpt) {
const val = (opOpt) ? opOpt.value : null;
this.props.actions.changeFilterOp(filter, val);
}
changeValue(filter, value) {
this.props.actions.changeFilterValue(filter, value);
}
removeFilter(filter) {
this.props.actions.removeFilter(filter);
}
addFilter() {
this.props.actions.addFilter({
id: shortid.generate(),
field: null,
op: null,
value: null,
});
}
render() {
const filters = this.props.filters.map((filter) => (
<div>
<Select
className="row"
multi={false}
name="select-column"
placeholder="Select column"
options={this.props.filterColumnOpts}
value={filter.field}
autosize={false}
onChange={this.changeField.bind(this, filter)}
/>
<div className="row">
<Select
className="col-sm-3"
multi={false}
name="select-op"
placeholder="Select operator"
options={this.state.opOpts.map((o) => ({ value: o, label: o }))}
value={filter.op}
autosize={false}
onChange={this.changeOp.bind(this, filter)}
/>
<div className="col-sm-6">
<input
type="text"
onChange={this.changeValue.bind(this, filter)}
className="form-control input-sm"
placeholder="Filter value"
/>
</div>
<div className="col-sm-3">
<Button
bsStyle="primary"
onClick={this.removeFilter.bind(this, filter)}
>
<i className="fa fa-minus" />
</Button>
</div>
</div>
</div>
)
);
return (
<div className="panel space-1">
<div className="panel-header">Filters</div>
<div className="panel-body">
{filters}
<Button
bsStyle="primary"
onClick={this.addFilter.bind(this)}
>
<i className="fa fa-plus" />Add Filter
</Button>
</div>
</div>
);
}
}
Filters.propTypes = propTypes;
Filters.defaultProps = defaultProps;
function mapStateToProps(state) {
return {
filterColumnOpts: state.filterColumnOpts,
filters: state.filters,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Filters);
@@ -1,68 +0,0 @@
import React from 'react';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
import SelectArray from './SelectArray';
const propTypes = {
actions: React.PropTypes.object,
metricsOpts: React.PropTypes.array,
metrics: React.PropTypes.array,
groupByColumnOpts: React.PropTypes.array,
groupByColumns: React.PropTypes.array,
};
const defaultProps = {
metricsOpts: [],
metrics: [],
groupByColumnOpts: [],
groupByColumns: [],
};
const GroupBy = (props) => {
const selects = [
{
key: 'groupByColumns',
title: 'Group By',
options: props.groupByColumnOpts,
value: props.groupByColumns,
multi: true,
width: '12',
},
{
key: 'metrics',
title: 'Metrics',
options: props.metricsOpts,
value: props.metrics,
multi: true,
width: '12',
}];
return (
<div className="panel">
<div className="panel-header">GroupBy</div>
<div className="panel-body">
<SelectArray selectArray={selects} />
</div>
</div>
);
};
GroupBy.propTypes = propTypes;
GroupBy.defaultProps = defaultProps;
function mapStateToProps(state) {
return {
metricsOpts: state.metricsOpts,
metrics: state.viz.formData.metrics,
groupByColumnOpts: state.groupByColumnOpts,
groupByColumns: state.viz.formData.groupByColumns,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(GroupBy);
@@ -1,68 +0,0 @@
import React from 'react';
import SelectArray from './SelectArray';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
const propTypes = {
actions: React.PropTypes.object,
columnOpts: React.PropTypes.array,
columns: React.PropTypes.array,
orderingOpts: React.PropTypes.array,
orderings: React.PropTypes.array,
};
const defaultProps = {
columnOpts: [],
columns: [],
orderingOpts: [],
orderings: [],
};
const NotGroupBy = (props) => {
const selects = [
{
key: 'columns',
title: 'Columns',
options: props.columnOpts,
value: props.columns,
multi: true,
width: '12',
},
{
key: 'orderings',
title: 'Orderings',
options: props.orderingOpts,
value: props.orderings,
multi: true,
width: '12',
}];
return (
<div className="panel">
<div className="panel-header">Not GroupBy</div>
<div className="panel-body">
<SelectArray selectArray={selects} />
</div>
</div>
);
};
NotGroupBy.propTypes = propTypes;
NotGroupBy.defaultProps = defaultProps;
function mapStateToProps(state) {
return {
columnOpts: state.columnOpts,
columns: state.viz.formData.columns,
orderingOpts: state.orderingOpts,
orderings: state.viz.formData.orderings,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(NotGroupBy);
@@ -1,61 +0,0 @@
import React from 'react';
import SelectArray from './SelectArray';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
import { timestampOptions, rowLimitOptions } from '../constants';
const propTypes = {
actions: React.PropTypes.object,
timeStampFormat: React.PropTypes.string,
rowLimit: React.PropTypes.number,
};
const defaultProps = {
timeStampFormat: null,
rowLimit: null,
};
const Options = (props) => {
const selects = [
{
key: 'timeStampFormat',
title: 'Timestamp Format',
options: timestampOptions.map((t) => ({ value: t[0], label: t[1] })),
value: props.timeStampFormat,
width: '12',
},
{
key: 'rowLimit',
title: 'Row Limit',
options: rowLimitOptions.map((r) => ({ value: r, label: r })),
value: props.rowLimit,
width: '12',
}];
return (
<div className="panel">
<div className="panel-header">Options</div>
<div className="panel-body">
<SelectArray selectArray={selects} />
</div>
</div>
);
};
Options.propTypes = propTypes;
Options.defaultProps = defaultProps;
function mapStateToProps(state) {
return {
timeStampFormat: state.viz.formData.timeStampFormat,
rowLimit: state.viz.formData.rowLimit,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Options);
@@ -1,74 +0,0 @@
import React from 'react';
import Select from 'react-select';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
const propTypes = {
actions: React.PropTypes.object,
selectArray: React.PropTypes.arrayOf(
React.PropTypes.shape({
key: React.PropTypes.string.isRequired,
title: React.PropTypes.string.isRequired,
options: React.PropTypes.array.isRequired,
value: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.array,
]),
width: React.PropTypes.string,
multi: React.PropTypes.bool,
})
).isRequired,
};
const defaultProps = {
selectArray: [],
};
class SelectArray extends React.Component {
changeSelectData(key, multi, opt) {
if (multi) this.props.actions.setFormData(key, opt);
else {
const val = opt ? opt.value : null;
this.props.actions.setFormData(key, val);
}
}
render() {
const selects = this.props.selectArray.map((obj) => (
<div
className={(obj.width) ? `col-sm-${obj.width}` : 'col-sm-6'}
key={obj.key}
>
<h5 className="section-heading">{obj.title}</h5>
<Select
multi={obj.multi}
name={`select-${obj.key}`}
options={obj.options}
value={obj.value}
autosize={false}
onChange={this.changeSelectData.bind(this, obj.key, obj.multi)}
/>
</div>
));
return (
<div>
{selects}
</div>
);
}
}
SelectArray.propTypes = propTypes;
SelectArray.defaultProps = defaultProps;
function mapStateToProps() {
return {};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(SelectArray);
@@ -1,88 +0,0 @@
import React from 'react';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/exploreActions';
import { connect } from 'react-redux';
import { sinceOptions, untilOptions } from '../constants';
import SelectArray from './SelectArray';
const propTypes = {
actions: React.PropTypes.object,
datasourceType: React.PropTypes.string,
timeColumnOpts: React.PropTypes.array,
timeColumn: React.PropTypes.string,
timeGrainOpts: React.PropTypes.array,
timeGrain: React.PropTypes.string,
since: React.PropTypes.string,
until: React.PropTypes.string,
};
const defaultProps = {
timeColumnOpts: [],
timeColumn: null,
timeGrainOpts: [],
timeGrain: null,
since: null,
until: null,
};
const TimeFilter = (props) => {
const isDatasourceTypeTable = props.datasourceType === 'table';
const timeColumnTitle = isDatasourceTypeTable ? 'Time Column' : 'Time Granularity';
const timeGrainTitle = isDatasourceTypeTable ? 'Time Grain' : 'Origin';
const selects = [
{
key: 'timeColumn',
title: timeColumnTitle,
options: props.timeColumnOpts,
value: props.timeColumn,
},
{
key: 'timeGrain',
title: timeGrainTitle,
options: props.timeGrainOpts,
value: props.timeGrain,
},
{
key: 'since',
title: 'Since',
options: sinceOptions.map((s) => ({ value: s, label: s })),
value: props.since,
},
{
key: 'until',
title: 'Until',
options: untilOptions.map((u) => ({ value: u, label: u })),
value: props.until,
}];
return (
<div className="panel">
<div className="panel-header">Time Filter</div>
<div className="panel-body">
<SelectArray selectArray={selects} />
</div>
</div>
);
};
TimeFilter.propTypes = propTypes;
TimeFilter.defaultProps = defaultProps;
function mapStateToProps(state) {
return {
datasourceType: state.datasourceType,
timeColumnOpts: state.timeColumnOpts,
timeColumn: state.viz.formData.timeColumn,
timeGrainOpts: state.timeGrainOpts,
timeGrain: state.viz.formData.timeGrain,
since: state.viz.formData.since,
until: state.viz.formData.until,
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actions, dispatch),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(TimeFilter);
@@ -1,76 +0,0 @@
import React from 'react';
import TimeFilter from './components/TimeFilter';
import ChartControl from './components/ChartControl';
import GroupBy from './components/GroupBy';
import SqlClause from './components/SqlClause';
import Filters from './components/Filters';
import NotGroupBy from './components/NotGroupBy';
import Options from './components/Options';
export const VIZ_TYPES = [
{ value: 'dist_bar', label: 'Distribution - Bar Chart', requiresTime: false },
{ value: 'pie', label: 'Pie Chart', requiresTime: false },
{ value: 'line', label: 'Time Series - Line Chart', requiresTime: true },
{ value: 'bar', label: 'Time Series - Bar Chart', requiresTime: true },
{ value: 'compare', label: 'Time Series - Percent Change', requiresTime: true },
{ value: 'area', label: 'Time Series - Stacked', requiresTime: true },
{ value: 'table', label: 'Table View', requiresTime: false },
{ value: 'markup', label: 'Markup', requiresTime: false },
{ value: 'pivot_table', label: 'Pivot Table', requiresTime: false },
{ value: 'separator', label: 'Separator', requiresTime: false },
{ value: 'word_cloud', label: 'Word Cloud', requiresTime: false },
{ value: 'treemap', label: 'Treemap', requiresTime: false },
{ value: 'cal_heatmap', label: 'Calendar Heatmap', requiresTime: true },
{ value: 'box_plot', label: 'Box Plot', requiresTime: false },
{ value: 'bubble', label: 'Bubble Chart', requiresTime: false },
{ value: 'big_number', label: 'Big Number with Trendline', requiresTime: false },
{ value: 'bubble', label: 'Bubble Chart', requiresTime: false },
{ value: 'histogram', label: 'Histogram', requiresTime: false },
{ value: 'sunburst', label: 'Sunburst', requiresTime: false },
{ value: 'sankey', label: 'Sankey', requiresTime: false },
{ value: 'directed_force', label: 'Directed Force Layout', requiresTime: false },
{ value: 'world_map', label: 'World Map', requiresTime: false },
{ value: 'filter_box', label: 'Filter Box', requiresTime: false },
{ value: 'iframe', label: 'iFrame', requiresTime: false },
{ value: 'para', label: 'Parallel Coordinates', requiresTime: false },
{ value: 'heatmap', label: 'Heatmap', requiresTime: false },
{ value: 'horizon', label: 'Horizon', requiresTime: false },
{ value: 'mapbox', label: 'Mapbox', requiresTime: false },
];
export const sinceOptions = ['1 hour ago', '12 hours ago', '1 day ago',
'7 days ago', '28 days ago', '90 days ago', '1 year ago'];
export const untilOptions = ['now', '1 day ago', '7 days ago',
'28 days ago', '90 days ago', '1 year ago'];
export const timestampOptions = [
['smart_date', 'Adaptative formating'],
['%m/%d/%Y', '"%m/%d/%Y" | 01/14/2019'],
['%Y-%m-%d', '"%Y-%m-%d" | 2019-01-14'],
['%Y-%m-%d %H:%M:%S',
'"%Y-%m-%d %H:%M:%S" | 2019-01-14 01:32:10'],
['%H:%M:%S', '"%H:%M:%S" | 01:32:10'],
];
export const rowLimitOptions = [10, 50, 100, 250, 500, 1000, 5000, 10000, 50000];
export const DefaultControls = (
<div>
<ChartControl />
<TimeFilter />
<GroupBy />
<SqlClause />
<Filters />
</div>
);
export const TableVizControls = (
<div>
<NotGroupBy />
<Options />
</div>
);
export const VIZ_CONTROL_MAPPING = {
table: TableVizControls,
};
@@ -1,49 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ExploreViewContainer from './components/ExploreViewContainer';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import { initialState } from './stores/store';
const exploreViewContainer = document.getElementById('js-explore-view-container');
const bootstrapData = JSON.parse(exploreViewContainer.getAttribute('data-bootstrap'));
import { exploreReducer } from './reducers/exploreReducer';
const bootstrappedState = Object.assign(initialState, {
datasources: bootstrapData.datasources,
datasourceId: parseInt(bootstrapData.datasource_id, 10),
datasourceType: bootstrapData.datasource_type,
sliceName: bootstrapData.viz.form_data.slice_name,
viz: {
jsonEndPoint: bootstrapData.viz.json_endpoint,
data: bootstrapData.viz.data,
columnFormats: bootstrapData.viz.column_formats,
formData: {
sliceId: bootstrapData.viz.form_data.slice_id,
vizType: bootstrapData.viz.form_data.viz_type,
timeColumn: bootstrapData.viz.form_data.granularity_sqla,
timeGrain: bootstrapData.viz.form_data.time_grain_sqla,
metrics: [bootstrapData.viz.form_data.metrics].map((m) => ({ value: m, label: m })),
since: bootstrapData.viz.form_data.since,
until: bootstrapData.viz.form_data.until,
having: bootstrapData.viz.form_data.having,
where: bootstrapData.viz.form_data.where,
rowLimit: bootstrapData.viz.form_data.row_limit,
timeStampFormat: bootstrapData.viz.form_data.table_timestamp_format,
},
},
});
const store = createStore(exploreReducer, bootstrappedState,
compose(applyMiddleware(thunk))
);
ReactDOM.render(
<Provider store={store}>
<ExploreViewContainer />
</Provider>,
exploreViewContainer
);
@@ -1,89 +0,0 @@
import { defaultFormData, defaultOpts } from '../stores/store';
import * as actions from '../actions/exploreActions';
import { addToArr, removeFromArr, alterInArr } from '../../../utils/reducerUtils';
const setFormInViz = function (state, action) {
const newFormData = Object.assign({}, state);
newFormData[action.key] = action.value;
return newFormData;
};
const setVizInState = function (state, action) {
switch (action.type) {
case actions.SET_FORM_DATA:
return Object.assign(
{},
state,
{ formData: setFormInViz(state.formData, action) }
);
default:
return state;
}
};
export const exploreReducer = function (state, action) {
const actionHandlers = {
[actions.SET_DATASOURCE]() {
return Object.assign({}, state, { datasourceId: action.datasourceId });
},
[actions.SET_TIME_COLUMN_OPTS]() {
return Object.assign({}, state, { timeColumnOpts: action.timeColumnOpts });
},
[actions.SET_TIME_GRAIN_OPTS]() {
return Object.assign({}, state, { timeGrainOpts: action.timeGrainOpts });
},
[actions.SET_GROUPBY_COLUMN_OPTS]() {
return Object.assign({}, state, { groupByColumnOpts: action.groupByColumnOpts });
},
[actions.SET_METRICS_OPTS]() {
return Object.assign({}, state, { metricsOpts: action.metricsOpts });
},
[actions.SET_COLUMN_OPTS]() {
return Object.assign({}, state, { columnOpts: action.columnOpts });
},
[actions.SET_ORDERING_OPTS]() {
return Object.assign({}, state, { orderingOpts: action.orderingOpts });
},
[actions.TOGGLE_SEARCHBOX]() {
return Object.assign({}, state, { searchBox: action.searchBox });
},
[actions.SET_FILTER_COLUMN_OPTS]() {
return Object.assign({}, state, { filterColumnOpts: action.filterColumnOpts });
},
[actions.ADD_FILTER]() {
return addToArr(state, 'filters', action.filter);
},
[actions.REMOVE_FILTER]() {
return removeFromArr(state, 'filters', action.filter);
},
[actions.CHANGE_FILTER_FIELD]() {
return alterInArr(state, 'filters', action.filter, { field: action.field });
},
[actions.CHANGE_FILTER_OP]() {
return alterInArr(state, 'filters', action.filter, { op: action.op });
},
[actions.CHANGE_FILTER_VALUE]() {
return alterInArr(state, 'filters', action.filter, { value: action.value });
},
[actions.RESET_FORM_DATA]() {
return Object.assign({}, state, defaultFormData);
},
[actions.CLEAR_ALL_OPTS]() {
return Object.assign({}, state, defaultOpts);
},
[actions.SET_DATASOURCE_TYPE]() {
return Object.assign({}, state, { datasourceType: action.datasourceType });
},
[actions.SET_FORM_DATA]() {
return Object.assign(
{},
state,
{ viz: setVizInState(state.viz, action) }
);
},
};
if (action.type in actionHandlers) {
return actionHandlers[action.type]();
}
return state;
};
@@ -1,53 +0,0 @@
// TODO: add datasource_type here after druid support is added
export const defaultFormData = {
sliceId: null,
vizType: null,
timeColumn: null,
timeGrain: null,
groupByColumns: [],
metrics: [],
since: null,
until: null,
having: null,
where: null,
columns: [],
orderings: [],
timeStampFormat: 'smart_date',
rowLimit: 50000,
searchBox: false,
whereClause: '',
havingClause: '',
filters: [],
};
export const initialState = {
datasources: null,
datasourceId: null,
datasourceType: null,
timeColumnOpts: [],
timeGrainOpts: [],
timeGrain: null,
groupByColumnOpts: [],
metricsOpts: [],
columnOpts: [],
orderingOpts: [],
searchBox: false,
whereClause: '',
havingClause: '',
filters: [],
filterColumnOpts: [],
viz: {
columnFormats: {},
formData: defaultFormData,
},
};
export const defaultOpts = {
timeColumnOpts: [],
timeGrainOpts: [],
groupByColumnOpts: [],
metricsOpts: [],
filterColumnOpts: [],
columnOpts: [],
orderingOpts: [],
};
@@ -1,50 +0,0 @@
import { it, describe } from 'mocha';
import { expect } from 'chai';
import shortid from 'shortid';
import * as actions from '../../../../javascripts/explorev2/actions/exploreActions';
import { initialState } from '../../../../javascripts/explorev2/stores/store';
import { exploreReducer } from '../../../../javascripts/explorev2/reducers/exploreReducer';
describe('reducers', () => {
it('should return new state with datasource id', () => {
const newState = exploreReducer(initialState, actions.setDatasource(1));
expect(newState.datasourceId).to.equal(1);
});
it('should return new state with search box toggled', () => {
const newState = exploreReducer(initialState, actions.toggleSearchBox(true));
expect(newState.searchBox).to.equal(true);
});
it('should return new state with added filter', () => {
const newFilter = {
id: shortid.generate(),
eq: 'value',
op: 'in',
col: 'vals',
};
const newState = exploreReducer(initialState, actions.addFilter(newFilter));
expect(newState.filters).to.deep.equal([newFilter]);
});
it('should return new state with removed filter', () => {
const filter1 = {
id: shortid.generate(),
eq: 'value',
op: 'in',
col: 'vals1',
};
const filter2 = {
id: shortid.generate(),
eq: 'value',
op: 'not in',
col: 'vals2',
};
const testState = {
initialState,
filters: [filter1, filter2],
};
const newState = exploreReducer(testState, actions.removeFilter(filter1));
expect(newState.filters).to.deep.equal([filter2]);
});
});
@@ -1,33 +0,0 @@
import React from 'react';
import Select from 'react-select';
import { Button } from 'react-bootstrap';
import QuerySearch from '../../../javascripts/SqlLab/components/QuerySearch';
import { shallow } from 'enzyme';
import { describe, it } from 'mocha';
import { expect } from 'chai';
describe('QuerySearch', () => {
const mockedProps = {
actions: {},
};
it('is valid', () => {
expect(
React.isValidElement(<QuerySearch {...mockedProps} />)
).to.equal(true);
});
it('should have two Select', () => {
const wrapper = shallow(<QuerySearch {...mockedProps} />);
expect(wrapper.find(Select)).to.have.length(2);
});
it('should have one input for searchText', () => {
const wrapper = shallow(<QuerySearch {...mockedProps} />);
expect(wrapper.find('input')).to.have.length(1);
});
it('should have one Button', () => {
const wrapper = shallow(<QuerySearch {...mockedProps} />);
expect(wrapper.find(Button)).to.have.length(1);
});
});
@@ -1,43 +0,0 @@
import React from 'react';
import Link from '../../../javascripts/SqlLab/components/Link';
import TableElement from '../../../javascripts/SqlLab/components/TableElement';
import { table } from './fixtures';
import { mount, shallow } from 'enzyme';
import { describe, it } from 'mocha';
import { expect } from 'chai';
describe('TableElement', () => {
const mockedProps = {
table,
};
it('renders', () => {
expect(
React.isValidElement(<TableElement />)
).to.equal(true);
});
it('renders with props', () => {
expect(
React.isValidElement(<TableElement {...mockedProps} />)
).to.equal(true);
});
it('has 3 Link elements', () => {
const wrapper = shallow(<TableElement {...mockedProps} />);
expect(wrapper.find(Link)).to.have.length(3);
});
it('has 14 columns', () => {
const wrapper = shallow(<TableElement {...mockedProps} />);
expect(wrapper.find('div.table-column')).to.have.length(14);
});
it('mounts', () => {
mount(<TableElement {...mockedProps} />);
});
it('sorts columns', () => {
const wrapper = mount(<TableElement {...mockedProps} />);
expect(wrapper.state().sortColumns).to.equal(false);
expect(wrapper.find('.col-name').first().text()).to.equal('id');
wrapper.find('.sort-cols').simulate('click');
expect(wrapper.state().sortColumns).to.equal(true);
expect(wrapper.find('.col-name').first().text()).to.equal('last_login');
});
});
-122
View File
@@ -1,122 +0,0 @@
{% extends "caravel/basic.html" %}
{% block head_js %}
{{ super() }}
{% with filename="dashboard" %}
{% include "caravel/partials/_script_tag.html" %}
{% endwith %}
{% endblock %}
{% block title %}[dashboard] {{ dashboard.dashboard_title }}{% endblock %}
{% block body %}
<div
class="dashboard container-fluid"
data-dashboard="{{ dashboard.json_data }}"
data-css="{{ dashboard.css }}"
data-user="{{ user_id }}"
>
{% include 'caravel/flash_wrapper.html' %}
<!-- Modal -->
<div class="modal fade" id="css_modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content css">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Dashboard CSS</h4>
<h6><strong>Styling applies to this dashboard only</strong></h6>
</div>
<div class="modal-body">
<select id="css_template" class="select2" style="margin-bottom: 5px;">
<option value="" data-css="">CSS template</option>
{% for t in templates %}
<option value="{{ t.id }}" data-css="{{t.css}}">
{{ t.template_name }}
</option>
{% endfor %}
</select><br>
<textarea id="dash_css" rows="30" cols="60">{{ dashboard.css }}</textarea>
<input type="hidden" id="dashboard_id" value="{{ dashboard.id }}" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="refresh_modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Refresh Interval</h4>
<h6><strong>Choose how frequent should the dashboard refresh</strong></h6>
</div>
<div class="modal-body">
<select id="refresh_dash_interval" class="select2" style="margin-bottom: 5px;">
<option value="0">Don't refresh</option>
<option value="10">10 seconds</option>
<option value="30">30 seconds</option>
<option value="60">1 minute</option>
<option value="300">5 minutes</option>
</select><br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
{% if not standalone_mode %}
<div id="add-slice-container"></div>
{% endif %}
<div class="title">
<div class="row">
<div class="col-md-8">
<h1>
<strong>
{{ dashboard.dashboard_title }}
</strong>
<span class="favstar" class_name="Dashboard" obj_id="{{ dashboard.id }}"></span>
</h1>
</div>
{% if not standalone_mode %}
<div class="col-md-4">
<div class="btn-group pull-right" role="group" >
<button type="button" id="refresh_dash" class="btn btn-default btn-sm" data-toggle="tooltip" title="Force refresh the whole dashboard">
<i class="fa fa-refresh"></i>
</button>
<button type="button" id="add-slice" class="btn btn-default btn-sm {{ "disabled disabledButton" if not dash_save_perm }}" data-toggle="modal" data-target="#add_slice_modal">
<i class="fa fa-plus" data-toggle="tooltip" title="Add a new slice to the dashboard"></i>
</button>
<button type="button" id="refresh_dash_periodic" class="btn btn-default btn-sm" data-toggle="modal" data-target="#refresh_modal">
<i class="fa fa-clock-o" data-toggle="tooltip" title="Decide how frequent should the dashboard refresh"></i>
</button>
<button type="button" id="filters" class="btn btn-default btn-sm" data-toggle="tooltip" title="View the list of active filters">
<i class="fa fa-filter"></i>
</button>
<button type="button" id="css" class="btn btn-default btn-sm{{ "disabled disabledButton" if not dash_edit_perm }} " data-toggle="modal" data-target="#css_modal">
<i class="fa fa-css3" data-toggle="tooltip" title="Edit the dashboard's CSS"></i>
</button>
<a id="editdash" class="btn btn-default btn-sm{{ "disabled disabledButton" if not dash_edit_perm }} " href="/dashboardmodelview/edit/{{ dashboard.id }}" title="Edit this dashboard's property" data-toggle="tooltip" >
<i class="fa fa-edit"></i>
</a>
<button type="button" id="savedash" class="btn btn-default btn-sm {{ "disabled disabledButton" if not dash_save_perm }}" data-toggle="tooltip" title="Save the current positioning and CSS">
<i class="fa fa-save"></i>
</button>
</div>
</div>
{% endif %}
</div>
</div>
<!-- gridster class used for backwards compatibility -->
<div id="grid-container" class="slice-grid gridster"></div>
</div>
{% endblock %}
-10
View File
@@ -1,10 +0,0 @@
<html>
<body>
<code>
<pre>{{ art }}
{{ title }}
{{ error_msg }}
</pre>
</code>
</body>
</html>
+2
View File
@@ -1,9 +1,11 @@
codeclimate-test-reporter
coveralls
flake8
mock
mysqlclient
nose
psycopg2
pyyaml
sphinx
sphinx-rtd-theme
sphinxcontrib.youtube
+4 -4
View File
@@ -87,9 +87,9 @@ qthelp:
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/caravel.qhcp"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/superset.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/caravel.qhc"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/superset.qhc"
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@@ -104,8 +104,8 @@ devhelp:
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/caravel"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/caravel"
@echo "# mkdir -p $$HOME/.local/share/devhelp/superset"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/superset"
@echo "# devhelp"
epub:
+2 -2
View File
@@ -21,7 +21,7 @@
<img src="_static/img/dash.png">
<div class="carousel-caption">
<div>
<h1>Caravel</h1>
<h1>Superset</h1>
<p>
an open source data visualization platform
</p>
@@ -80,7 +80,7 @@
<hr/>
<div class="container">
<div class="jumbotron">
<h1>Caravel</h1>
<h1>Superset</h1>
<p>
is an open source data visualization platform that provides easy
exploration of your data and allows you to create and share
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
rm -rf _build
make html
#cp -r ../caravel/assets/images/ _build/html/_static/img/
cp -r ../caravel/assets/images/ _static/img/
rm -rf /tmp/caravel-docs
cp -r _build/html /tmp/caravel-docs
#cp -r ../superset/assets/images/ _build/html/_static/img/
cp -r ../superset/assets/images/ _static/img/
rm -rf /tmp/superset-docs
cp -r _build/html /tmp/superset-docs
+7 -7
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# caravel documentation build configuration file, created by
# superset documentation build configuration file, created by
# sphinx-quickstart on Thu Dec 17 15:42:06 2015.
#
# This file is execfile()d with the current directory set to its
@@ -51,7 +51,7 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = "Caravel's documentation"
project = "Superset's documentation"
copyright = None
author = u'Maxime Beauchemin'
@@ -209,7 +209,7 @@ html_show_copyright = False
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'caraveldoc'
htmlhelp_basename = 'supersetdoc'
# -- Options for LaTeX output ---------------------------------------------
@@ -231,7 +231,7 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'caravel.tex', u'Caravel Documentation',
(master_doc, 'superset.tex', u'Superset Documentation',
u'Maxime Beauchemin', 'manual'),
]
@@ -261,7 +261,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'Caravel', u'caravel Documentation',
(master_doc, 'Superset', u'superset Documentation',
[author], 1)
]
@@ -275,8 +275,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Caravel', u'Caravel Documentation',
author, 'Caravel', 'One line description of project.',
(master_doc, 'Superset', u'Superset Documentation',
author, 'Superset', 'One line description of project.',
'Miscellaneous'),
]
+3 -3
View File
@@ -1,7 +1,7 @@
Druid
=====
Caravel works well with Druid, though currently not all
Superset works well with Druid, though currently not all
advanced features out of Druid are covered. This page clarifies what is
covered and what isn't and explains how to use some of the features.
@@ -15,7 +15,7 @@ Supported
Aggregations
------------
Common aggregations, or Druid metrics can be defined and used in Caravel.
Common aggregations, or Druid metrics can be defined and used in Superset.
The first and simpler use case is to use the checkbox matrix expose in your
datasource's edit view (``Sources -> Druid Datasources ->
[your datasource] -> Edit -> [tab] List Druid Column``).
@@ -34,7 +34,7 @@ documentation.
Post-Aggregations
-----------------
Druid supports post aggregation and this works in Caravel. All you have to
Druid supports post aggregation and this works in Superset. All you have to
do is creating a metric, much like you would create an aggregation manually,
but specify ``postagg`` as a ``Metric Type``. You then have to provide a valid
json post-aggregation definition (as specified in the Druid docs) in the
+17 -7
View File
@@ -4,7 +4,7 @@ FAQ
Can I query/join multiple tables at one time?
---------------------------------------------
Not directly no. A Caravel SQLAlchemy datasource can only be a single table
Not directly no. A Superset SQLAlchemy datasource can only be a single table
or a view.
When working with tables, the solution would be to materialize
@@ -14,15 +14,15 @@ through some scheduled batch process.
A view is a simple logical layer that abstract an arbitrary SQL queries as
a virtual table. This can allow you to join and union multiple tables, and
to apply some transformation using arbitrary SQL expressions. The limitation
there is your database performance as Caravel effectively will run a query
there is your database performance as Superset effectively will run a query
on top of your query (view). A good practice may be to limit yourself to
joining your main large table to one or many small tables only, and avoid
using ``GROUP BY`` where possible as Caravel will do its own ``GROUP BY`` and
using ``GROUP BY`` where possible as Superset will do its own ``GROUP BY`` and
doing the work twice might slow down performance.
Whether you use a table or a view, the important factor is whether your
database is fast enough to serve it in an interactive fashion to provide
a good user experience in Caravel.
a good user experience in Superset.
How BIG can my data source be?
@@ -42,7 +42,7 @@ framework, in the meantime, we've tagged a few pull requests as
``example`` to give people examples of how to contribute new
visualizations.
https://github.com/airbnb/caravel/issues?q=label%3Aexample+is%3Aclosed
https://github.com/airbnb/superset/issues?q=label%3Aexample+is%3Aclosed
Why are my queries timing out?
@@ -53,14 +53,14 @@ it's because the web server is timing out web requests. If you want to
increase the default (50), you can specify the timeout when starting the
web server with the ``-t`` flag, which is expressed in seconds.
``caravel runserver -t 300``
``superset runserver -t 300``
Why is the map not visible in the mapbox visualization?
-------------------------------------------------------
You need to register to mapbox.com, get an API key and configure it as
``MAPBOX_API_KEY`` in ``caravel_config.py``.
``MAPBOX_API_KEY`` in ``superset_config.py``.
How to add dynamic filters to a dashboard?
@@ -109,3 +109,13 @@ for dealing with the time boundary filtering mentioned above.
But what happens with filtering when dealing with slices coming from
different tables or databases? If the column name is shared, the filter will
be applied, it's as simple as that.
Why does fabmanager or superset freezed/hung/not responding when started (my home directory is NFS mounted)?
-----------------------------------------------------------------------------------------
superset creates and uses an sqlite database at ``~/.superset/superset.db``. Sqlite is known to `don't work well if used on NFS`__ due to broken file locking implementation on NFS.
__ https://www.sqlite.org/lockingv3.html
One work around is to create a symlink from ~/.superset to a directory located on a non-NFS partition.
Another work around is to change where superset stores the sqlite database by adding ``SQLALCHEMY_DATABASE_URI = 'sqlite:////new/localtion/superset.db'`` in superset_config.py (create the file if needed), then adding the directory where superset_config.py lives to PYTHONPATH environment variable (e.g. ``export PYTHONPATH=/opt/logs/sandbox/airbnb/``).
+5 -7
View File
@@ -1,15 +1,13 @@
Caravel's documentation
'''''''''''''''''''''''
Superset's documentation
''''''''''''''''''''''''
Caravel is a data exploration platform designed to be visual, intuitive
Superset is a data exploration platform designed to be visual, intuitive
and interactive.
.. image:: _static/img/caravel.jpg
----------------
.. warning:: This project used to be named Panoramix and has been renamed
to Caravel in March 2016
.. warning:: This project was originally named Panoramix, was renamed to
Caravel in March 2016, and is currently named Superset as of November 2016
Overview
=======================================
+51 -49
View File
@@ -4,19 +4,19 @@ Installation & Configuration
Getting Started
---------------
Caravel is tested using Python 2.7 and Python 3.4+. Python 3 is the recommended version,
Superset is tested using Python 2.7 and Python 3.4+. Python 3 is the recommended version,
Python 2.6 won't be supported.
OS dependencies
---------------
Caravel stores database connection information in its metadata database.
Superset stores database connection information in its metadata database.
For that purpose, we use the ``cryptography`` Python library to encrypt
connection passwords. Unfortunately this library has OS level dependencies.
You may want to attempt the next step
("Caravel installation and initialization") and come back to this step if
("Superset installation and initialization") and come back to this step if
you encounter an error.
Here's how to install them:
@@ -47,7 +47,7 @@ attempt it, download `get-pip.py <https://bootstrap.pypa.io/get-pip.py>`_, and r
Python virtualenv
-----------------
It is recommended to install Caravel inside a virtualenv. Python 3 already ships virtualenv, for
It is recommended to install Superset inside a virtualenv. Python 3 already ships virtualenv, for
Python 2 you need to install it. If it's packaged for your operating systems install it from there
otherwise you can install from pip: ::
@@ -73,40 +73,40 @@ and ``setuptools`` libraries.::
pip install --upgrade setuptools pip
Caravel installation and initialization
---------------------------------------
Follow these few simple steps to install Caravel.::
Superset installation and initialization
----------------------------------------
Follow these few simple steps to install Superset.::
# Install caravel
pip install caravel
# Install superset
pip install superset
# Create an admin user
fabmanager create-admin --app caravel
fabmanager create-admin --app superset
# Initialize the database
caravel db upgrade
superset db upgrade
# Load some data to play with
caravel load_examples
superset load_examples
# Create default roles and permissions
caravel init
superset init
# Start the web server on port 8088
caravel runserver -p 8088
superset runserver -p 8088
# To start a development web server, use the -d switch
# caravel runserver -d
# superset runserver -d
After installation, you should be able to point your browser to the right
hostname:port `http://localhost:8088 <http://localhost:8088>`_, login using
the credential you entered while creating the admin account, and navigate to
`Menu -> Admin -> Refresh Metadata`. This action should bring in all of
your datasources for Caravel to be aware of, and they should show up in
your datasources for Superset to be aware of, and they should show up in
`Menu -> Datasources`, from where you can start playing with your data!
Please note that *gunicorn*, Caravel default application server, does not
Please note that *gunicorn*, Superset default application server, does not
work on Windows so you need to use the development web server.
The development web server though is not intended to be used on production systems
so better use a supported platform that can run *gunicorn*.
@@ -114,14 +114,14 @@ so better use a supported platform that can run *gunicorn*.
Configuration behind a load balancer
------------------------------------
If you are running caravel behind a load balancer or reverse proxy (e.g. NGINX
If you are running superset behind a load balancer or reverse proxy (e.g. NGINX
or ELB on AWS), you may need to utilise a healthcheck endpoint so that your
load balancer knows if your caravel instance is running. This is provided
load balancer knows if your superset instance is running. This is provided
at ``/health`` which will return a 200 response containing "OK" if the
webserver is running.
If the load balancer is inserting X-Forwarded-For/X-Forwarded-Proto headers, you
should set `ENABLE_PROXY_FIX = True` in the caravel config file to extract and use
should set `ENABLE_PROXY_FIX = True` in the superset config file to extract and use
the headers.
@@ -129,16 +129,16 @@ Configuration
-------------
To configure your application, you need to create a file (module)
``caravel_config.py`` and make sure it is in your PYTHONPATH. Here are some
``superset_config.py`` and make sure it is in your PYTHONPATH. Here are some
of the parameters you can copy / paste in that configuration module: ::
#---------------------------------------------------------
# Caravel specific config
# Superset specific config
#---------------------------------------------------------
ROW_LIMIT = 5000
CARAVEL_WORKERS = 4
SUPERSET_WORKERS = 4
CARAVEL_WEBSERVER_PORT = 8088
SUPERSET_WEBSERVER_PORT = 8088
#---------------------------------------------------------
#---------------------------------------------------------
@@ -149,10 +149,10 @@ of the parameters you can copy / paste in that configuration module: ::
# The SQLAlchemy connection string to your database backend
# This connection defines the path to the database that stores your
# caravel metadata (slices, connections, tables, dashboards, ...).
# superset metadata (slices, connections, tables, dashboards, ...).
# Note that the connection information to connect to the datasources
# you want to explore are managed directly in the web UI
SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/caravel.db'
SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db'
# Flask-WTF flag for CSRF
CSRF_ENABLED = True
@@ -161,24 +161,24 @@ of the parameters you can copy / paste in that configuration module: ::
MAPBOX_API_KEY = ''
This file also allows you to define configuration parameters used by
Flask App Builder, the web framework used by Caravel. Please consult
Flask App Builder, the web framework used by Superset. Please consult
the `Flask App Builder Documentation
<http://flask-appbuilder.readthedocs.org/en/latest/config.html>`_
for more information on how to configure Caravel.
for more information on how to configure Superset.
Please make sure to change:
* *SQLALCHEMY_DATABASE_URI*, by default it is stored at *~/.caravel/caravel.db*
* *SQLALCHEMY_DATABASE_URI*, by default it is stored at *~/.superset/superset.db*
* *SECRET_KEY*, to a long random string
Database dependencies
---------------------
Caravel does not ship bundled with connectivity to databases, except
Superset does not ship bundled with connectivity to databases, except
for Sqlite, which is part of the Python standard library.
You'll need to install the required packages for the database you
want to use as your metadata database as well as the packages needed to
connect to the databases you want to access through Caravel.
connect to the databases you want to access through Superset.
Here's a list of some of the recommended packages.
@@ -203,6 +203,8 @@ Here's a list of some of the recommended packages.
+---------------+-------------------------------------+-------------------------------------------------+
| SparkSQL | ``pip install pyhive`` | ``jdbc+hive://`` |
+---------------+-------------------------------------+-------------------------------------------------+
| Greenplum | ``pip install psycopg2`` | ``postgresql+psycopg2://`` |
+---------------+-------------------------------------+-------------------------------------------------+
Note that many other database are supported, the main criteria being the
existence of a functional SqlAlchemy dialect and Python driver. Googling
@@ -213,18 +215,18 @@ database you want to connect to should get you to the right place.
Caching
-------
Caravel uses `Flask-Cache <https://pythonhosted.org/Flask-Cache/>`_ for
Superset uses `Flask-Cache <https://pythonhosted.org/Flask-Cache/>`_ for
caching purpose. Configuring your caching backend is as easy as providing
a ``CACHE_CONFIG``, constant in your ``caravel_config.py`` that
a ``CACHE_CONFIG``, constant in your ``superset_config.py`` that
complies with the Flask-Cache specifications.
Flask-Cache supports multiple caching backends (Redis, Memcached,
SimpleCache (in-memory), or the local filesystem). If you are going to use
Memcached please use the pylibmc client library as python-memcached does
not handle storing binary data correctly. If you use Redis, please install
[python-redis](https://pypi.python.org/pypi/redis).
`python-redis <https://pypi.python.org/pypi/redis>`.
For setting your timeouts, this is done in the Caravel metadata and goes
For setting your timeouts, this is done in the Superset metadata and goes
up the "timeout searchpath", from your slice configuration, to your
data source's configuration, to your database's and ultimately falls back
into your global default defined in ``CACHE_CONFIG``.
@@ -252,7 +254,7 @@ Schemas (Postgres & Redshift)
Postgres and Redshift, as well as other database,
use the concept of **schema** as a logical entity
on top of the **database**. For Caravel to connect to a specific schema,
on top of the **database**. For Superset to connect to a specific schema,
there's a **schema** parameter you can set in the table form.
@@ -284,7 +286,7 @@ Druid
* Navigate to your datasources
Note that you can run the ``caravel refresh_druid`` command to refresh the
Note that you can run the ``superset refresh_druid`` command to refresh the
metadata from your Druid cluster(s)
@@ -293,10 +295,10 @@ CORS
The extra CORS Dependency must be installed:
caravel[cors]
superset[cors]
The following keys in `caravel_config.py` can be specified to configure CORS:
The following keys in `superset_config.py` can be specified to configure CORS:
* ``ENABLE_CORS``: Must be set to True in order to enable CORS
@@ -307,16 +309,16 @@ Upgrading
Upgrading should be as straightforward as running::
pip install caravel --upgrade
caravel db upgrade
caravel init
pip install superset --upgrade
superset db upgrade
superset init
SQL Lab
-------
SQL Lab is a powerful SQL IDE that works with all SQLAlchemy compatible
databases out there. By default, queries are run in a web request, and
may eventually timeout as queries exceed the maximum duration of a web
request in your environment, whether it'd be a reverse proxy or the Caravel
request in your environment, whether it'd be a reverse proxy or the Superset
server itself.
In the modern analytics world, it's not uncommon to run large queries that
@@ -324,7 +326,7 @@ run for minutes or hours.
To enable support for long running queries that
execute beyond the typical web request's timeout (30-60 seconds), it is
necessary to deploy an asynchronous backend, which consist of one or many
Caravel worker, which is implemented as a Celery worker, and a Celery
Superset worker, which is implemented as a Celery worker, and a Celery
broker for which we recommend using Redis or RabbitMQ.
It's also preferable to setup an async result backend as a key value store
@@ -333,20 +335,20 @@ details to come as to how to set this up here soon.
SQL Lab supports templating in queries, and it's possible to override
the default Jinja context in your environment by defining the
``JINJA_CONTEXT_ADDONS`` in your caravel configuration. Objects referenced
``JINJA_CONTEXT_ADDONS`` in your superset configuration. Objects referenced
in this dictionary are made available for users to use in their SQL.
Making your own build
---------------------
For more advanced users, you may want to build Caravel from sources. That
For more advanced users, you may want to build Superset from sources. That
would be the case if you fork the project to add features specific to
your environment.::
# assuming $CARAVEL_HOME as the root of the repo
cd $CARAVEL_HOME/caravel/assets
# assuming $SUPERSET_HOME as the root of the repo
cd $SUPERSET_HOME/superset/assets
npm install
npm run prod
cd $CARAVEL_HOME
cd $SUPERSET_HOME
python setup.py install
+23 -6
View File
@@ -1,14 +1,25 @@
Security
========
Security in Caravel is handled by Flask AppBuilder (FAB). FAB is a
Security in Superset is handled by Flask AppBuilder (FAB). FAB is a
"Simple and rapid application development framework, built on top of Flask.".
FAB provides authentication, user management, permissions and roles.
Provided Roles
--------------
Caravel ships with 3 roles that are handled by Caravel itself. You can
assume that these 3 roles will stay up-to-date as Caravel evolves.
Superset ships with a set of roles that are handled by Superset itself.
You can assume that these roles will stay up-to-date as Superset evolves.
Even though it's possible for ``Admin`` usrs to do so, it is not recommended
that you alter these roles in any way by removing
or adding permissions to them as these roles will be re-synchronized to
their original values as you run your next ``superset init`` command.
Since it's not recommended to alter the roles described here, it's right
to assume that your security strategy should be to compose user access based
on these base roles and roles that you create. For instance you could
create a role ``Financial Analyst`` that would be made of set of permissions
to a set of data sources (tables) and/or databases. Users would then be
granted ``Gamma``, ``Financial Analyst``, and perhaps ``sql_lab``.
Admin
"""""
@@ -33,6 +44,12 @@ mostly content consumers, though they can create slices and dashboards.
Also note that when Gamma users look at the dashboards and slices list view,
they will only see the objects that they have access to.
sql_lab
"""""""
The ``sql_lab`` role grants access to SQL Lab. Note that while ``Admin``
users have access to all databases by default, both ``Alpha`` and ``Gamma``
users need to be given access on a per database basis.
Managing Gamma per data source access
-------------------------------------
@@ -59,17 +76,17 @@ Customizing
The permissions exposed by FAB are very granular and allow for a great level
of customization. FAB creates many permissions automagically for each model
that is create (can_add, can_delete, can_show, can_edit, ...) as well as for
each view. On top of that, Caravel can expose more granular permissions like
each view. On top of that, Superset can expose more granular permissions like
``all_datasource_access``.
We do not recommend altering the 3 base roles as there
are a set of assumptions that Caravel build upon. It is possible though for
are a set of assumptions that Superset build upon. It is possible though for
you to create your own roles, and union them to existing ones.
Permissions
"""""""""""
Roles are composed of a set of permissions, and Caravel has many categories
Roles are composed of a set of permissions, and Superset has many categories
of permissions. Here are the different categories of permissions:
- **Model & action**: models are entities like ``Dashboard``,
+6 -3
View File
@@ -9,7 +9,7 @@ Feature Overview
----------------
- Connects to just about any database backend
- A multi-tab environment to work on multiple queries at a time
- A smooth flow to visualize your query results using Caravel's rich
- A smooth flow to visualize your query results using Superset's rich
visualization capabilities
- Browse database metadata: tables, columns, indexes, partitions
- Support for long-running queries
@@ -21,6 +21,9 @@ Feature Overview
`Jinja templating language <http://jinja.pocoo.org/docs/dev/>`_
which allows for using macros in your SQL code
Extra features
--------------
- Hit ``alt + enter`` as a keyboard shortcut to run your query
Templating with Jinja
---------------------
@@ -42,7 +45,7 @@ Available macros
''''''''''''''''
We expose certain modules from Python's standard library in
Caravel's Jinja context:
Superset's Jinja context:
- ``time``: ``time``
- ``datetime``: ``datetime.datetime``
- ``uuid``: ``uuid``
@@ -53,5 +56,5 @@ Caravel's Jinja context:
`Jinja's builtin filters <http://jinja.pocoo.org/docs/dev/templates/>`_ can be also be applied where needed.
.. autoclass:: caravel.jinja_context.PrestoContext
.. autoclass:: superset.jinja_context.PrestoTemplateProcessor
:members:
+4 -4
View File
@@ -3,7 +3,7 @@ Tutorial
This basic linear tutorial will take you through connecting to a database,
adding a table, creating a slice and a dashboard. First you'll need to tell
Caravel where to find the database you want to
Superset where to find the database you want to
query. First go to the database menu
.. image:: _static/img/tutorial/db_menu.png
@@ -29,7 +29,7 @@ plus (``+``) sign there (similar to the one ).
Now enter the name of the table in the ``Table Name`` textbox, and select
the database you just created in the ``Database`` dropdown, hit save. At this
moment, Caravel fetched the column names, their data types and tries to guess
moment, Superset fetched the column names, their data types and tries to guess
which fields are metrics in dimensions. From the list view, edit the table
that you just created by clicking the tiny pen icon.
@@ -42,9 +42,9 @@ showing you the list of columns in your table as well as their data types.
.. image:: _static/img/tutorial/matrix.png
:scale: 30 %
Click the checkboxes here that inform Caravel how your columns should be
Click the checkboxes here that inform Superset how your columns should be
shown in the explore view, and which metrics should be created. Make sure
to inform Caravel about your date columns. You could also create
to inform Superset about your date columns. You could also create
"SQL expression" columns here, or metrics in that tab as aggregate expressions,
but let's not do that just yet. Hit ``save``.
+3 -3
View File
@@ -2,11 +2,11 @@ Videos
======
Here is a collection of short videos showing different aspect
of Caravel.
of Superset.
Quick Intro
'''''''''''
This video demonstrates how Caravel works at a high level, it shows how
This video demonstrates how Superset works at a high level, it shows how
to navigate through datasets and dashboards that are already available.
.. youtube:: https://www.youtube.com/watch?v=3Txm_nj_R7M
@@ -41,7 +41,7 @@ to toggle them on dashboards.
Adding a Table
''''''''''''''
This videos shows you how to expose a new table in Caravel, and how to
This videos shows you how to expose a new table in Superset, and how to
define the semantics on how this can be accessed by others in the ``Explore``
and ``Dashboard`` views.
+2 -1
View File
@@ -1,4 +1,5 @@
cd caravel/assets/
cd superset/assets/
rm build/*
npm run prod
cd ../..
python setup.py register
+2 -2
View File
@@ -1,9 +1,9 @@
#!/usr/bin/env bash
echo $DB
rm -f .coverage
export CARAVEL_CONFIG=tests.caravel_test_config
export SUPERSET_CONFIG=tests.superset_test_config
set -e
caravel/bin/caravel version -v
superset/bin/superset version -v
export SOLO_TEST=1
# e.g. tests.core_tests:CoreTests.test_templated_sql_json
nosetests $1
+7 -7
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env bash
echo $DB
rm ~/.caravel/unittests.db
rm ~/.caravel/celerydb.sqlite
rm ~/.caravel/celery_results.sqlite
rm ~/.superset/unittests.db
rm ~/.superset/celerydb.sqlite
rm ~/.superset/celery_results.sqlite
rm -f .coverage
export CARAVEL_CONFIG=tests.caravel_test_config
export SUPERSET_CONFIG=tests.superset_test_config
set -e
caravel/bin/caravel db upgrade
caravel/bin/caravel db upgrade # running twice on purpose as a test
caravel/bin/caravel version -v
superset/bin/superset db upgrade
superset/bin/superset db upgrade # running twice on purpose as a test
superset/bin/superset version -v
python setup.py nosetests
coveralls
+3 -3
View File
@@ -1,5 +1,5 @@
[metadata]
name = Caravel
name = Superset
summary = a data exploration platform
description-file = README.md
author = Maxime Beauchemin
@@ -7,7 +7,7 @@ author-email = maximebeauchemin@gmail.com
license = Apache License, Version 2.0
[files]
packages = caravel
packages = superset
[build_sphinx]
source-dir = docs/
@@ -22,7 +22,7 @@ verbosity=3
detailed-errors=1
with-coverage=1
nocapture=1
cover-package=caravel
cover-package=superset
[pycodestyle]
max-line-length=90
+6 -6
View File
@@ -4,13 +4,13 @@ import json
from setuptools import setup, find_packages
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
PACKAGE_DIR = os.path.join(BASE_DIR, 'caravel', 'static', 'assets')
PACKAGE_DIR = os.path.join(BASE_DIR, 'superset', 'static', 'assets')
PACKAGE_FILE = os.path.join(PACKAGE_DIR, 'package.json')
with open(PACKAGE_FILE) as package_file:
version_string = json.load(package_file)['version']
setup(
name='caravel',
name='superset',
description=(
"A interactive data visualization platform build on SqlAlchemy "
"and druid.io"),
@@ -18,10 +18,10 @@ setup(
packages=find_packages(),
include_package_data=True,
zip_safe=False,
scripts=['caravel/bin/caravel'],
scripts=['superset/bin/superset'],
install_requires=[
'celery==3.1.23',
'cryptography==1.4',
'cryptography==1.5.3',
'flask-appbuilder==1.8.1',
'flask-cache==0.13.1',
'flask-migrate==1.5.1',
@@ -57,9 +57,9 @@ setup(
],
author='Maxime Beauchemin',
author_email='maximebeauchemin@gmail.com',
url='https://github.com/airbnb/caravel',
url='https://github.com/airbnb/superset',
download_url=(
'https://github.com/airbnb/caravel/tarball/' + version_string),
'https://github.com/airbnb/superset/tarball/' + version_string),
classifiers=[
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
+8 -6
View File
@@ -13,16 +13,18 @@ from flask_appbuilder import SQLA, AppBuilder, IndexView
from flask_appbuilder.baseviews import expose
from flask_cache import Cache
from flask_migrate import Migrate
from caravel.source_registry import SourceRegistry
from superset.source_registry import SourceRegistry
from werkzeug.contrib.fixers import ProxyFix
from caravel import utils
from superset import utils
APP_DIR = os.path.dirname(__file__)
CONFIG_MODULE = os.environ.get('CARAVEL_CONFIG', 'caravel.config')
CONFIG_MODULE = os.environ.get('SUPERSET_CONFIG', 'superset.config')
app = Flask(__name__)
app.config.from_object(CONFIG_MODULE)
conf = app.config
if not app.debug:
# In production mode, add log handler to sys.stderr.
app.logger.addHandler(logging.StreamHandler())
@@ -66,11 +68,11 @@ if app.config.get('UPLOAD_FOLDER'):
class MyIndexView(IndexView):
@expose('/')
def index(self):
return redirect('/caravel/welcome')
return redirect('/superset/welcome')
appbuilder = AppBuilder(
app, db.session,
base_template='caravel/base.html',
base_template='superset/base.html',
indexview=MyIndexView,
security_manager_class=app.config.get("CUSTOM_SECURITY_MANAGER"))
@@ -84,4 +86,4 @@ module_datasource_map = app.config.get("DEFAULT_MODULE_DS_MAP")
module_datasource_map.update(app.config.get("ADDITIONAL_MODULE_DS_MAP"))
SourceRegistry.register_sources(module_datasource_map)
from caravel import views, config # noqa
from superset import views, config # noqa
+3
View File
@@ -0,0 +1,3 @@
{
"presets" : ["airbnb", "es2015", "react"],
}

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Before

Width:  |  Height:  |  Size: 459 KiB

After

Width:  |  Height:  |  Size: 459 KiB

Before

Width:  |  Height:  |  Size: 702 KiB

After

Width:  |  Height:  |  Size: 702 KiB

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 328 KiB

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 552 KiB

After

Width:  |  Height:  |  Size: 552 KiB

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Some files were not shown because too many files have changed in this diff Show More