Compare commits
286 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddeabdd048 | ||
|
|
3ed45ab98c | ||
|
|
ca08e7051e | ||
|
|
1fb21b8b45 | ||
|
|
c581ea8661 | ||
|
|
f19d1958c5 | ||
|
|
9c99be510b | ||
|
|
7a08cdcb1c | ||
|
|
f24ddfd467 | ||
|
|
23a8ea5636 | ||
|
|
2c04d3c250 | ||
|
|
337454b646 | ||
|
|
b7f46ebe75 | ||
|
|
10773f96a7 | ||
|
|
b97a8275d4 | ||
|
|
081bdca71e | ||
|
|
62959ca38b | ||
|
|
fe68bc31c3 | ||
|
|
3d2c791ff1 | ||
|
|
d40ce52139 | ||
|
|
122891c29b | ||
|
|
c1d9918abe | ||
|
|
d93b1fc686 | ||
|
|
02c5cac26f | ||
|
|
6566377740 | ||
|
|
db6b2f3ae1 | ||
|
|
c31210b96d | ||
|
|
dcc6f2a18f | ||
|
|
0c0666caa0 | ||
|
|
243eeadfd6 | ||
|
|
9ba5b49d8a | ||
|
|
c870bd414e | ||
|
|
4b01e92509 | ||
|
|
513a090cdc | ||
|
|
abe79d1427 | ||
|
|
b81968dc20 | ||
|
|
66cc546a30 | ||
|
|
6e899ac55f | ||
|
|
6b52384024 | ||
|
|
0a1d8db357 | ||
|
|
6f68ddb505 | ||
|
|
4f59abf189 | ||
|
|
5c441f4ddb | ||
|
|
be023aba8d | ||
|
|
53990201bc | ||
|
|
37783d685f | ||
|
|
25fdcaca8b | ||
|
|
ce6e7c1359 | ||
|
|
91167665b1 | ||
|
|
f374345860 | ||
|
|
d3b50cb92e | ||
|
|
a58194bdb0 | ||
|
|
5f3484ac59 | ||
|
|
e14b74fdbf | ||
|
|
56f28859b7 | ||
|
|
f3cdb3b787 | ||
|
|
b35f6b0a94 | ||
|
|
5574cfef59 | ||
|
|
c3015583ce | ||
|
|
7cc2c930ed | ||
|
|
2662bf19df | ||
|
|
62e3fe2345 | ||
|
|
7d25d171e2 | ||
|
|
c5859c7254 | ||
|
|
dd7b4b8310 | ||
|
|
93551a65b8 | ||
|
|
7eafbabe65 | ||
|
|
43dd948476 | ||
|
|
75e7f2d22c | ||
|
|
26662eed9e | ||
|
|
121b1d0951 | ||
|
|
398036d77e | ||
|
|
59d5fcf88c | ||
|
|
1f8e48b374 | ||
|
|
7bf19b1232 | ||
|
|
1590b8c7e5 | ||
|
|
22522fc05f | ||
|
|
c9b59fab1f | ||
|
|
69152e087a | ||
|
|
652e572b56 | ||
|
|
65c89f54dc | ||
|
|
edf5c0e83b | ||
|
|
a4abbfe126 | ||
|
|
7b28bcef15 | ||
|
|
8042ac876e | ||
|
|
82bc907088 | ||
|
|
e2b572d9e2 | ||
|
|
e71596dc45 | ||
|
|
c3be58db43 | ||
|
|
3d77a12aa9 | ||
|
|
36deb8da71 | ||
|
|
05ee8c0e36 | ||
|
|
5ca55a5585 | ||
|
|
1b330a8c55 | ||
|
|
696678c981 | ||
|
|
20aec3cfca | ||
|
|
4ded37e71e | ||
|
|
0674ed846c | ||
|
|
3107152f5b | ||
|
|
5b19528662 | ||
|
|
357773c631 | ||
|
|
5e43d074c3 | ||
|
|
08bdcd52b8 | ||
|
|
0b8522be50 | ||
|
|
c02a7fe763 | ||
|
|
dcd5bdeb00 | ||
|
|
562b4f0415 | ||
|
|
6160a3fdff | ||
|
|
0779da6d24 | ||
|
|
740624ba01 | ||
|
|
2969cc9993 | ||
|
|
9a8c3a0447 | ||
|
|
e817382efd | ||
|
|
422d1feb3e | ||
|
|
2b0cb2b0a5 | ||
|
|
705d09d3d0 | ||
|
|
9114d86ecd | ||
|
|
ad4a950b56 | ||
|
|
bd480e0c6b | ||
|
|
af3415b040 | ||
|
|
b4a96bd840 | ||
|
|
9d8d421384 | ||
|
|
f6ffc00748 | ||
|
|
e35016f07d | ||
|
|
af8e2523a8 | ||
|
|
492df94b2a | ||
|
|
b62f7e2820 | ||
|
|
5cc2fc157c | ||
|
|
266c049f2d | ||
|
|
4e848c8cb5 | ||
|
|
efff1ac4a1 | ||
|
|
fc64a75fbd | ||
|
|
dd9f431b6f | ||
|
|
c894c54d00 | ||
|
|
4d349c7885 | ||
|
|
675b819e0a | ||
|
|
09f1083c50 | ||
|
|
47be3ef3ea | ||
|
|
9dd7778597 | ||
|
|
efffa925ed | ||
|
|
fa9bc92c95 | ||
|
|
227c66c2c5 | ||
|
|
e91bc9dfcc | ||
|
|
bc29035bda | ||
|
|
f10e453c9b | ||
|
|
d4b59b36a8 | ||
|
|
4f644cd0ca | ||
|
|
ed2935ec69 | ||
|
|
ea72c6b018 | ||
|
|
2df6ab36bf | ||
|
|
10ea63557a | ||
|
|
55e462d90b | ||
|
|
73393925c0 | ||
|
|
f9852bc807 | ||
|
|
6e1901e8e8 | ||
|
|
87582962d9 | ||
|
|
3de2698657 | ||
|
|
ec1f0221cd | ||
|
|
4d900c9ee1 | ||
|
|
3a758900eb | ||
|
|
1ea7178d17 | ||
|
|
c85c9988df | ||
|
|
34f68073a2 | ||
|
|
acc880c4df | ||
|
|
557b557503 | ||
|
|
3018356588 | ||
|
|
ede4dffcb7 | ||
|
|
cad392eb76 | ||
|
|
0296158100 | ||
|
|
b2a4692a02 | ||
|
|
2fbadea9e3 | ||
|
|
dc05be36a6 | ||
|
|
dac0d1d0dc | ||
|
|
459f7160ac | ||
|
|
aff524d843 | ||
|
|
3a91667e92 | ||
|
|
3e0d3584f7 | ||
|
|
1e47d6fb41 | ||
|
|
d5ba88b407 | ||
|
|
ce1e18b31b | ||
|
|
ec84aa7577 | ||
|
|
8b4d72cf32 | ||
|
|
85e6e65a47 | ||
|
|
7cad3655f5 | ||
|
|
b9e7f292c3 | ||
|
|
fc85034c60 | ||
|
|
f5e3d0cc02 | ||
|
|
fe377e8b94 | ||
|
|
5bb87138e9 | ||
|
|
579e58206e | ||
|
|
172b6ce892 | ||
|
|
0cc8eff1c3 | ||
|
|
3b023e5eaa | ||
|
|
615d8f1624 | ||
|
|
b4409ace21 | ||
|
|
dbee6aca1f | ||
|
|
acfe62eaf7 | ||
|
|
527a8af060 | ||
|
|
a5a931a670 | ||
|
|
2f05efaf12 | ||
|
|
83ef8a2e12 | ||
|
|
c564881867 | ||
|
|
b16930f35d | ||
|
|
2d910e3f07 | ||
|
|
daa1420c8e | ||
|
|
cea310e50b | ||
|
|
fcdd5c6752 | ||
|
|
2ace73e9a1 | ||
|
|
80cfb08794 | ||
|
|
1edc2b91cf | ||
|
|
1f58e18b6f | ||
|
|
f2bf316058 | ||
|
|
9cd38fa1ed | ||
|
|
edb0111775 | ||
|
|
de4f9e8d1a | ||
|
|
461e41cd61 | ||
|
|
716406198e | ||
|
|
68592aeddf | ||
|
|
b927ff6eef | ||
|
|
ce50e6e4fe | ||
|
|
167ed33bba | ||
|
|
0ee1abf31a | ||
|
|
6a0a1af67e | ||
|
|
f85481d51b | ||
|
|
00b6b0ac68 | ||
|
|
1546b1ae71 | ||
|
|
1e94498d9d | ||
|
|
0f7189b859 | ||
|
|
a6e0f1b75a | ||
|
|
543c22bb50 | ||
|
|
07e067cf0b | ||
|
|
6c256a34a9 | ||
|
|
6b2eb04a73 | ||
|
|
898d80ba38 | ||
|
|
ea8e4ad05b | ||
|
|
27aeac6859 | ||
|
|
8da371e324 | ||
|
|
0c59fe933d | ||
|
|
e169c67760 | ||
|
|
3a5a927dc6 | ||
|
|
2d419e4253 | ||
|
|
87869a29c9 | ||
|
|
544211f5ec | ||
|
|
f6ac95e2dd | ||
|
|
63bef2f844 | ||
|
|
4a8cd04de6 | ||
|
|
85806624db | ||
|
|
1ac2273984 | ||
|
|
a8c29c4ffe | ||
|
|
31af01c4f2 | ||
|
|
b1bba96d04 | ||
|
|
c5c730224e | ||
|
|
7441cf7d39 | ||
|
|
45c72d25df | ||
|
|
3fff631b32 | ||
|
|
bfa2891b23 | ||
|
|
5715f52fef | ||
|
|
1f2126f463 | ||
|
|
27ed0b37bf | ||
|
|
cdbd2f8507 | ||
|
|
e46ba2b4a4 | ||
|
|
1c338ba742 | ||
|
|
2b7673ad5d | ||
|
|
2f27353015 | ||
|
|
1b8c3f420a | ||
|
|
a3a070855c | ||
|
|
e84c6393b8 | ||
|
|
7413dd9f4b | ||
|
|
9cbd667eb7 | ||
|
|
37fb56c61c | ||
|
|
404a94cadb | ||
|
|
0807a8d016 | ||
|
|
4a9888157e | ||
|
|
83fbdcceac | ||
|
|
b070ef5fdb | ||
|
|
7d380dcd14 | ||
|
|
a15dbd992d | ||
|
|
52c5d235af | ||
|
|
495f6460a4 | ||
|
|
a96024d0e7 | ||
|
|
99b84d2909 | ||
|
|
24728b8b47 | ||
|
|
9750e49df8 | ||
|
|
bf31783d0c | ||
|
|
87eacf88c3 | ||
|
|
1dbfb99ead |
407
.pylintrc
Normal file
@@ -0,0 +1,407 @@
|
||||
[MASTER]
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
jobs=1
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Allow optimization of some AST trees. This will activate a peephole AST
|
||||
# optimizer, which will apply various small optimizations. For instance, it can
|
||||
# be used to obtain the result of joining multiple strings with the addition
|
||||
# operator. Joining a lot of strings can lead to a maximum recursion error in
|
||||
# Pylint and this flag can prevent that. It has one side effect, the resulting
|
||||
# AST will be different than the one from reality. This option is deprecated
|
||||
# and it will be removed in Pylint 2.0.
|
||||
optimize-ast=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
#enable=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=standarderror-builtin,long-builtin,dict-view-method,intern-builtin,suppressed-message,no-absolute-import,unpacking-in-except,apply-builtin,delslice-method,indexing-exception,old-raise-syntax,print-statement,cmp-builtin,reduce-builtin,useless-suppression,coerce-method,input-builtin,cmp-method,raw_input-builtin,nonzero-method,backtick,basestring-builtin,setslice-method,reload-builtin,oct-method,map-builtin-not-iterating,execfile-builtin,old-octal-literal,zip-builtin-not-iterating,buffer-builtin,getslice-method,metaclass-assignment,xrange-builtin,long-suffix,round-builtin,range-builtin-not-iterating,next-method-called,dict-iter-method,parameter-unpacking,unicode-builtin,unichr-builtin,import-star-module-level,raising-string,filter-builtin-not-iterating,old-ne-operator,using-cmp-argument,coerce-builtin,file-builtin,old-division,hex-method
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, msvs
|
||||
# (visual studio) and html. You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Put messages in a separate file for each module / package specified on the
|
||||
# command line instead of printing them on stdout. Reports (if any) will be
|
||||
# written in a file name "pylint_global.[txt|html]". This option is deprecated
|
||||
# and it will be removed in Pylint 2.0.
|
||||
files-output=no
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=yes
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
#msg-template=
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=i,j,k,ex,Run,_,d,e,v,o,l,x,ts
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,bar,baz,toto,tutu,tata
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Regular expression matching correct argument names
|
||||
argument-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for argument names
|
||||
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct method names
|
||||
method-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for method names
|
||||
method-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct variable names
|
||||
variable-rgx=[a-z_][a-z0-9_]{1,30}$
|
||||
|
||||
# Naming hint for variable names
|
||||
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct inline iteration names
|
||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Naming hint for inline iteration names
|
||||
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Regular expression matching correct constant names
|
||||
const-rgx=(([A-Za-z_][A-Za-z0-9_]*)|(__.*__))$
|
||||
|
||||
# Naming hint for constant names
|
||||
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Regular expression matching correct class names
|
||||
class-rgx=[A-Z_][a-zA-Z0-9]+$
|
||||
|
||||
# Naming hint for class names
|
||||
class-name-hint=[A-Z_][a-zA-Z0-9]+$
|
||||
|
||||
# Regular expression matching correct class attribute names
|
||||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Naming hint for class attribute names
|
||||
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Regular expression matching correct module names
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Naming hint for module names
|
||||
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Regular expression matching correct attribute names
|
||||
attr-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for attribute names
|
||||
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct function names
|
||||
function-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for function names
|
||||
function-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=10
|
||||
|
||||
|
||||
[ELIF]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=90
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,dict-separator
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,XXX,TODO
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=numpy,pandas,alembic.op,sqlalchemy,alembic.context,flask_appbuilder.security.sqla.PermissionView.role,flask_appbuilder.Model.metadata,flask_appbuilder.Base.metadata
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,_cb
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,future.builtins
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,__new__,setUp
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,_fields,_replace,_source,_make
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=optparse
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
||||
@@ -17,6 +17,7 @@ env:
|
||||
- TRAVIS_NODE_VERSION="5.11"
|
||||
matrix:
|
||||
- TOX_ENV=javascript
|
||||
- TOX_ENV=pylint
|
||||
- TOX_ENV=py34-postgres
|
||||
- TOX_ENV=py34-sqlite
|
||||
- TOX_ENV=py27-mysql
|
||||
@@ -34,5 +35,4 @@ install:
|
||||
- pip install --upgrade pip
|
||||
- pip install tox tox-travis
|
||||
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
|
||||
- npm install
|
||||
script: tox -e $TOX_ENV
|
||||
|
||||
315
CHANGELOG.md
@@ -1,5 +1,312 @@
|
||||
## Change Log
|
||||
|
||||
### 0.17.2 (2017/03/29 14:46 +00:00)
|
||||
- [25fdcac](https://github.com/airbnb/superset/commit/25fdcaca8b1dd32c05ecd7fd57d4cf32e8f72447) v0.17.2 (@mistercrunch)
|
||||
- [ce6e7c1](https://github.com/airbnb/superset/commit/ce6e7c135943130fb104b10d284aca93e4f2d4dc) [hotfix] missing logging import in db_engined_specs (@mistercrunch)
|
||||
- [9116766](https://github.com/airbnb/superset/commit/91167665b19ca094fd51dadf9538c12fd61bc55a) Track both query start time and button push time to track delay (#2502) (@mistercrunch)
|
||||
- [f374345](https://github.com/airbnb/superset/commit/f374345860f4a3e307ea1772b099ce038868aa71) Adding a .pylintrc file and a bit of linting (#2507) (@mistercrunch)
|
||||
- [d3b50cb](https://github.com/airbnb/superset/commit/d3b50cb92e046de316725f0e02fdd816573b6234) [explore] remove grey background in standalone mode (#2503) (@mistercrunch)
|
||||
- [a58194b](https://github.com/airbnb/superset/commit/a58194bdb06a966c6d642bdfa7c80195cc9cf996) 0.17.2rc4 (@mistercrunch)
|
||||
- [5f3484a](https://github.com/airbnb/superset/commit/5f3484ac5981f2dd6aa447cbc2e4f2a9afe4518c) Handle errors when the MQ is down (#2494) (@mistercrunch)
|
||||
- [e14b74f](https://github.com/airbnb/superset/commit/e14b74fdbf876aeeeea7baa125926dcf719a0098) [explore] fixing bugs in controls (#2496) (@mistercrunch)
|
||||
- [56f2885](https://github.com/airbnb/superset/commit/56f28859b7315767d3e312aa3777b777156a658d) Fixing filter_box css padding (#2498) (@mistercrunch)
|
||||
- [f3cdb3b](https://github.com/airbnb/superset/commit/f3cdb3b787b804071a8f183569027169e432cb46) Add ibm_db_sa TimeStamp and Datatime Grain Spec. (#2500) (@openmax)
|
||||
- [b35f6b0](https://github.com/airbnb/superset/commit/b35f6b0a94df2017b3bd908c6589d786f9feec6b) 0.17.2rc3 (@mistercrunch)
|
||||
- [5574cfe](https://github.com/airbnb/superset/commit/5574cfef59a7326487f7cebf9a575070ab19a3c2) Fixing out-of-sync security (#2493) (@mistercrunch)
|
||||
- [c301558](https://github.com/airbnb/superset/commit/c3015583ce09f259bf36e018ebd0820f9c0cb92f) Stabilizing master (#2478) (@mistercrunch)
|
||||
- [7cc2c93](https://github.com/airbnb/superset/commit/7cc2c930ede176242cc9066baf16c00fccd23e01) [docs] adding notes on the Public role (#2486) (@mistercrunch)
|
||||
- [2662bf1](https://github.com/airbnb/superset/commit/2662bf19df690c0a133318406a6935a27245a82f) v0.17.2rc2 (@mistercrunch)
|
||||
- [62e3fe2](https://github.com/airbnb/superset/commit/62e3fe2345afa6fa8b8cb0da7f20bb44b48a0e54) [hotfix] SqlaTable has no attribute column_cls (@mistercrunch)
|
||||
- [7d25d17](https://github.com/airbnb/superset/commit/7d25d171e29dce859c455a03d33cc4c3054775c7) [release] update to 0.17.2rc1 (#2492) (@ascott)
|
||||
- [c5859c7](https://github.com/airbnb/superset/commit/c5859c7254448d2cdbc877b00580bd95fa6e7e2e) [hotfix] druid queries 'There was no query executed' issue (@mistercrunch)
|
||||
- [dd7b4b8](https://github.com/airbnb/superset/commit/dd7b4b8310e27310f80a0415a2bd877f3098127b) Revert "[sql-lab] revert react-virtualized-select (#2489)" (#2491) (@ascott)
|
||||
- [93551a6](https://github.com/airbnb/superset/commit/93551a65b845f430aaefaa50f75a40857f1b6ed6) only fetch tables if we have a schema, otherwise reset options. (#2490) (@ascott)
|
||||
- [7eafbab](https://github.com/airbnb/superset/commit/7eafbabe65b430a2347ed6bba3e08d1f4d8c1946) [sql-lab] revert react-virtualized-select (#2489) (@ascott)
|
||||
- [43dd948](https://github.com/airbnb/superset/commit/43dd948476190cf75649164f57a9b73687ca3d99) [sql-lab] performance updates - make ui more responsive (#2469) (@ascott)
|
||||
- [75e7f2d](https://github.com/airbnb/superset/commit/75e7f2d22c7185f2a6393b7ded7a2b5d0558cfca) [hotfix] bumping QUERY_UPDATE_FREQ from 1000 to 2000ms (@mistercrunch)
|
||||
- [26662ee](https://github.com/airbnb/superset/commit/26662eed9e08475a4c41d715f5a3608876a1afd1) Fixed CSS syntax for background linear-gradient (#2482) (@songyanho)
|
||||
- [121b1d0](https://github.com/airbnb/superset/commit/121b1d0951049ac30ab35a225269c03451d14bbc) Refactoring more in the connector base classes (#2431) (@mistercrunch)
|
||||
- [398036d](https://github.com/airbnb/superset/commit/398036d77e0c817796e3735797eae56e80dce437) [hotfix] 'NoneType' object has no attribute 'upper' (@mistercrunch)
|
||||
- [59d5fcf](https://github.com/airbnb/superset/commit/59d5fcf88c0f484a189c7f02968982b2d39512ad) [hotfix] fixing checkboxes in Tables->Columns (@mistercrunch)
|
||||
- [1f8e48b](https://github.com/airbnb/superset/commit/1f8e48b374adb091bf41e60634e99b132a37bf62) [sqllab] assign types for visualize flow (#2458) (@mistercrunch)
|
||||
- [7bf19b1](https://github.com/airbnb/superset/commit/7bf19b12327504aec2be2c2fd36404efb1faec05) [WiP] making doubling '%' not required (#2459) (@mistercrunch)
|
||||
- [1590b8c](https://github.com/airbnb/superset/commit/1590b8c7e5a070183a3c0e3153aec63992e3c60f) Speeding up polling by not checking access (#2466) (@mistercrunch)
|
||||
- [22522fc](https://github.com/airbnb/superset/commit/22522fc05f8859b94299576f4a8b07bd42eaba00) [sql-lab] improve table select performance (#2457) (@ascott)
|
||||
- [c9b59fa](https://github.com/airbnb/superset/commit/c9b59fab1fded7fa08fc9d44a8c18427865e11dd) Update INTHEWILD.md (#2455) (@jakubczaplicki)
|
||||
- [69152e0](https://github.com/airbnb/superset/commit/69152e087a2b9900e53a8a97ed318c271f725649) [explore] remove 'SQL Clauses' section when using Druid (#2449) (@mistercrunch)
|
||||
- [652e572](https://github.com/airbnb/superset/commit/652e572b56054cefdfe83403db2125a9d85f5a6a) [sql-lab] make results table scroll in static container (#2426) (@ascott)
|
||||
- [65c89f5](https://github.com/airbnb/superset/commit/65c89f54dc845ee4f77b230fb334eba225bb14e6) [hotfix] merging db migration scripts (#2448) (@mistercrunch)
|
||||
- [edf5c0e](https://github.com/airbnb/superset/commit/edf5c0e83b2c9023ef3ad9cabc7ce19d32551d84) [dist_bar] fix x scroll when overflowing (#2440) (@mistercrunch)
|
||||
- [a4abbfe](https://github.com/airbnb/superset/commit/a4abbfe1266ab1593ba82ef23d6e733b3d8e8e33) Fix formatting in README.md (#2441) (@imagejan)
|
||||
- [7b28bce](https://github.com/airbnb/superset/commit/7b28bcef15cd37284780e605f5076ede2864afb4) Fix documentation for adding a Redshift database (#2447) (@alexdebrie)
|
||||
- [8042ac8](https://github.com/airbnb/superset/commit/8042ac876e80c08d72489287777cb1e9672b177a) [explore] improved filters (#2330) (@mistercrunch)
|
||||
- [82bc907](https://github.com/airbnb/superset/commit/82bc907088be26206a7c8d1c84311ca399eb73b9) fix a bug in pie chart (#2423) (@yileic)
|
||||
- [e2b572d](https://github.com/airbnb/superset/commit/e2b572d9e229fee503128cab8d7bff02a9cd881b) Prevent alarming users with stacktrace when using sqlite (@mistercrunch)
|
||||
- [e71596d](https://github.com/airbnb/superset/commit/e71596dc45f96e6a3fdfb09f5ee6b00a9cdd018c) make dualline thumbnail have consistent size as other thumbnails (#2434) (@yileic)
|
||||
- [c3be58d](https://github.com/airbnb/superset/commit/c3be58db437746c168e706e8a5710e2a1d363d0d) Add verbose name to db and druid cluster (#2429) (@bkyryliuk)
|
||||
- [3d77a12](https://github.com/airbnb/superset/commit/3d77a12aa9b27375a02f7092c16a2883bd171913) Display the first partition. (#2425) (@bkyryliuk)
|
||||
- [36deb8d](https://github.com/airbnb/superset/commit/36deb8da7157893d08d01148ab538f963aacf140) Allow users to alter column types (#2424) (@mistercrunch)
|
||||
|
||||
### 0.17.1 (2017/03/16 15:44 +00:00)
|
||||
- [05ee8c0](https://github.com/airbnb/superset/commit/05ee8c0e3675b0ab88cf85d061971177ed871144) v0.17.1 (@mistercrunch)
|
||||
- [5ca55a5](https://github.com/airbnb/superset/commit/5ca55a55858a59f6340284cfe4081fd26d2be489) [hotfix on dist_bar] bringing back overwritten handling of ints and tuples (@mistercrunch)
|
||||
- [1b330a8](https://github.com/airbnb/superset/commit/1b330a8c55f0ec114970855c6682627434216ab5) Use connector registry for metrics (#2420) (@bkyryliuk)
|
||||
- [696678c](https://github.com/airbnb/superset/commit/696678c9816d934c10243395e12e8483e2a42df0) Replace query once query response returned (#2415) (@vera-liu)
|
||||
- [20aec3c](https://github.com/airbnb/superset/commit/20aec3cfcad082f921cdfc347382b2d0d4a4fd54) Use connector registry to fetch the table column class. (#2419) (@bkyryliuk)
|
||||
- [4ded37e](https://github.com/airbnb/superset/commit/4ded37e71edf1306ee9652cf32324b5dc14a1328) [hotfix] handle missing or empty column type (@mistercrunch)
|
||||
- [0674ed8](https://github.com/airbnb/superset/commit/0674ed846c478bd97e7b6953c375b5a3ab26802b) Use list instead of numpy array (#2412) (@bkyryliuk)
|
||||
- [3107152](https://github.com/airbnb/superset/commit/3107152f5bb973b8b1a9c5cf3bc2bee1d7f47e0d) Revert "Preprocess the where clauses." (#2411) (@bkyryliuk)
|
||||
- [5b19528](https://github.com/airbnb/superset/commit/5b19528662f5ea645ead5b066144d69469ecbf7c) Display full name. (#2378) (@bkyryliuk)
|
||||
- [357773c](https://github.com/airbnb/superset/commit/357773c631ad39260109ec45d9c313d6d45cea89) Preprocess the where clauses. (#2405) (@bkyryliuk)
|
||||
- [5e43d07](https://github.com/airbnb/superset/commit/5e43d074c3be9b909fe0b473f00e743b4ba9d56e) [explore ] templating can now reference query elements (#2388) (@mistercrunch)
|
||||
- [08bdcd5](https://github.com/airbnb/superset/commit/08bdcd52b856f5ed6c91ab9c3805cf259223da0a) Fix bad d3.format metric setting and/or value === Infinity (#2399) (@mistercrunch)
|
||||
- [0b8522b](https://github.com/airbnb/superset/commit/0b8522be502988d8b9bf64a8ea203068adf5957d) [filter_box] fix time filter and inverted instantFilter (#2402) (@mistercrunch)
|
||||
- [c02a7fe](https://github.com/airbnb/superset/commit/c02a7fe7634b311c6f42968a9f7bafef147092e1) Add more tests to Save Modal specs (#2313) (@vera-liu)
|
||||
- [dcd5bde](https://github.com/airbnb/superset/commit/dcd5bdeb00b8333d67234bde79397b5195fbb8f9) fix unicode issues (#2308 #2282) (#2401) (@asdf2014)
|
||||
- [562b4f0](https://github.com/airbnb/superset/commit/562b4f04156f20a2aeec8d2c27758571d0aaa514) Do not silence error message for query. (#2396) (@bkyryliuk)
|
||||
- [6160a3f](https://github.com/airbnb/superset/commit/6160a3fdffdcebe618191462633414c0dff7de30) Implement stop query functionality. (#2387) (@bkyryliuk)
|
||||
- [0779da6](https://github.com/airbnb/superset/commit/0779da6d244c5686f6ab5faf2ef5067019266460) Keep column order in .csv (#2377) (@bkyryliuk)
|
||||
- [740624b](https://github.com/airbnb/superset/commit/740624ba01edcfa305d6ff0a2676d413e59377f4) Fix monthly time grain in sqllite (#2380) (@bkyryliuk)
|
||||
- [2969cc9](https://github.com/airbnb/superset/commit/2969cc9993325acc730b794f9d0d0b07fe1a60ec) Refactoring Druid & SQLa into a proper "Connector" interface (#2362) (@mistercrunch)
|
||||
- [9a8c3a0](https://github.com/airbnb/superset/commit/9a8c3a044710bcfc578b77b498af1f15685f2bca) [table] metric ordering is wrong in some cases (#2373) (@mistercrunch)
|
||||
- [e817382](https://github.com/airbnb/superset/commit/e817382efd5f18e09534a70f95cc47332288356e) Add more tests to Filter spec (#2315) (@vera-liu)
|
||||
- [422d1fe](https://github.com/airbnb/superset/commit/422d1feb3e2ac964b77cd9756ed0fc1293056373) 0.17.1rc2 (@mistercrunch)
|
||||
- [2b0cb2b](https://github.com/airbnb/superset/commit/2b0cb2b0a56d033cd59c13ae3326c3d922d53b22) Fix partition query (#2353) (@bkyryliuk)
|
||||
- [705d09d](https://github.com/airbnb/superset/commit/705d09d3d07e05e3a5e070d25a348a45288d7721) Remove duplicate (#2351) (@bkyryliuk)
|
||||
- [9114d86](https://github.com/airbnb/superset/commit/9114d86ecd0dbd0ad20c24d56f1fd29604de2047) Add hive to superset + monkey patch the pyhive (#2134) (@bkyryliuk)
|
||||
- [ad4a950](https://github.com/airbnb/superset/commit/ad4a950b5646abef823357274298014292af091f) Fixes filters emitted from table viz (#2335) (@mistercrunch)
|
||||
- [bd480e0](https://github.com/airbnb/superset/commit/bd480e0c6b9d5127d96d8c18fd53ebe6193aec70) Fix duplicate property DruidDatasource.database (#2348) (@mistercrunch)
|
||||
- [af3415b](https://github.com/airbnb/superset/commit/af3415b0406399ba41c1592d31440b722556f90b) [filter_box] option to delay filtering with apply button (#2338) (@mistercrunch)
|
||||
- [b4a96bd](https://github.com/airbnb/superset/commit/b4a96bd8409d38462ea14d2fbafa2f975defd741) Fix for RuntimeError: dictionary changed size during iteration (#2320) (@moranrf)
|
||||
- [9d8d421](https://github.com/airbnb/superset/commit/9d8d4213840cc07d95ac971437632aeae4ff58b5) [hotfix] fix world map (@mistercrunch)
|
||||
- [f6ffc00](https://github.com/airbnb/superset/commit/f6ffc007481c658293ae209982dfc369c0f82f95) Allow running Flask Blueprints alongside Superset (#2337) (@mistercrunch)
|
||||
- [e35016f](https://github.com/airbnb/superset/commit/e35016f07d3880cd557f48c72c617e68d61b125d) remove unneeded tooltip/description text (#2303) (@ascott)
|
||||
- [af8e252](https://github.com/airbnb/superset/commit/af8e2523a820080e06aaf3e50ff309ada1422bc6) fix version (#2336) (@ascott)
|
||||
- [492df94](https://github.com/airbnb/superset/commit/492df94b2a3a4767af40edfb5ab074632baaea4d) [sqllab] reserved words should be upper case (#2316) (@mistercrunch)
|
||||
- [b62f7e2](https://github.com/airbnb/superset/commit/b62f7e2820fc140a318b69b84c54a8a5fe965ed0) [version] use rc for production only releases (#2334) (@ascott)
|
||||
- [5cc2fc1](https://github.com/airbnb/superset/commit/5cc2fc157cfc2dc14363424533eade67e1f48543) v0.17.1 (#2333) (@ascott)
|
||||
- [266c049](https://github.com/airbnb/superset/commit/266c049f2df96bb7c815c91dd9f650fbefd6b513) Fix bug with breakdown (#2312) (@vera-liu)
|
||||
- [4e848c8](https://github.com/airbnb/superset/commit/4e848c8cb55be50c5c5ddbb58694b20d4223a2a3) Updating CHANGELOG (@mistercrunch)
|
||||
- [efff1ac](https://github.com/airbnb/superset/commit/efff1ac4a1d2b26ef932ac6937be0456fb901c09) Temp hack to make druid filters work in dashboard (#2300) (@vera-liu)
|
||||
- [fc64a75](https://github.com/airbnb/superset/commit/fc64a75fbd5a3aed7a62b741a9a057acb2b9dca8) v0.17.0 (#2298) (@vera-liu)
|
||||
|
||||
### 0.17.0 (2017/02/28 19:47 +00:00)
|
||||
0.17.0 introduces major changes that **YOU CANNOT ROLLBACK FROM**, take
|
||||
a backup of your app's database before starting the upgrade progress.
|
||||
|
||||
* **bookmarks:** the URL scheme for the explore view changed, but previous
|
||||
URLs are still supported, though there may be some edge cases there
|
||||
* **translations**: 0.17.0 has a major regression around translations as
|
||||
much of the logic in the explore view moved from the backend to the frontend
|
||||
where we currently do not have a translation framework setup. If
|
||||
translations are important to you, you should skip 0.17.* and get involved
|
||||
in getting translations to work well in future versions. `1.0` will have
|
||||
translations
|
||||
|
||||
- [dd9f431](https://github.com/airbnb/superset/commit/dd9f431b6fe6179ebdae015a375640adccb388c0) v0.17.0 (@mistercrunch)
|
||||
- [c894c54](https://github.com/airbnb/superset/commit/c894c54d00af8b6981c8aafcde02be7195973a38) [table] Allowing to show the time grain in table view (#2294) (@mistercrunch)
|
||||
- [4d349c7](https://github.com/airbnb/superset/commit/4d349c788559ee3fd7de6792d0e153b98d799487) [hotfix] Fix filter for sqlalchemy and druid (#2293) (@vera-liu)
|
||||
- [675b819](https://github.com/airbnb/superset/commit/675b819e0a2601b23e21b37aedf0b49757e218f4) Revert "[hotfix] Fix druid filters" (#2292) (@vera-liu)
|
||||
- [09f1083](https://github.com/airbnb/superset/commit/09f1083c509a690c1f5fcf68f9823fea661ba80f) [table viz] allow showing time granularity in table (#2284) (#2291) (@vera-liu)
|
||||
- [47be3ef](https://github.com/airbnb/superset/commit/47be3ef3ea385925b5ef67cdecb0ba36adc2b3db) Fixing bugs in Sankey diagrams (#2290) (@mistercrunch)
|
||||
- [9dd7778](https://github.com/airbnb/superset/commit/9dd7778597e3429c7bb93788172a2850dd33656e) [table viz] allow showing time granularity in table (#2284) (@mistercrunch)
|
||||
- [efffa92](https://github.com/airbnb/superset/commit/efffa925edf3f54f76acb03660a5b85728133004) rc7 (@mistercrunch)
|
||||
- [fa9bc92](https://github.com/airbnb/superset/commit/fa9bc92c9551669d5dc1fb99f06e8d49052938d1) [hotfix] filters broken on multi-datasource dashboards (@mistercrunch)
|
||||
- [227c66c](https://github.com/airbnb/superset/commit/227c66c2c50dd88bdc1ae4eb81dcd2f8189aea98) [hotfix] add regex for druid filters (#2288) (@vera-liu)
|
||||
- [e91bc9d](https://github.com/airbnb/superset/commit/e91bc9dfcceeb22b88efd57e6defe80d520079f0) added gcc-c++ for RHEL OS dependencies (#2286) (@soccerties)
|
||||
- [bc29035](https://github.com/airbnb/superset/commit/bc29035bdadad7c2df6d430661314a02d1bafea4) 0.16.1rc6 (@mistercrunch)
|
||||
- [f10e453](https://github.com/airbnb/superset/commit/f10e453c9bf0a0988769e7a5f126e94e40b50a49) Fixing bar charts x_axis labels (#2280) (@mistercrunch)
|
||||
- [d4b59b3](https://github.com/airbnb/superset/commit/d4b59b36a801e0f50cde85c15da0538848a5a202) Fixed a bug when querying with schema path to Redshift/Postgresql (#1789) (@sungjuly)
|
||||
- [4f644cd](https://github.com/airbnb/superset/commit/4f644cd0cae02af685cb12e42edc2875cb32acca) 0.16.1rc5 (@mistercrunch)
|
||||
- [ed2935e](https://github.com/airbnb/superset/commit/ed2935ec69d72765d66d8c9afe45e0a0b070cc6a) Fixing multi value parsing on old URL (#2277) (@mistercrunch)
|
||||
- [ea72c6b](https://github.com/airbnb/superset/commit/ea72c6b0188e9c5a662358e89c95801b319296f8) [bugfix] css editor dooesn't pop up (#2243) (@mistercrunch)
|
||||
- [2df6ab3](https://github.com/airbnb/superset/commit/2df6ab36bf5dab7366ff76fc8d9454cb62a49046) Add Udemy to INTHEWILD (#2275) (@sungjuly)
|
||||
- [10ea635](https://github.com/airbnb/superset/commit/10ea63557a29859e09cbc5bf93a539a9b9f3ea55) [hotfix] not grouped by -2 (@mistercrunch)
|
||||
- [55e462d](https://github.com/airbnb/superset/commit/55e462d90b0d01baca8d5c5f2877220b039524ce) 0.16.1rc3 (@mistercrunch)
|
||||
- [7339392](https://github.com/airbnb/superset/commit/73393925c0482007e498afa745be6d20d8c49b83) [hotfix] Table view doesn't allow SELECT (no group by) (#2274) (@mistercrunch)
|
||||
- [f9852bc](https://github.com/airbnb/superset/commit/f9852bc807f5335987d0d3d46c665b975a5fb0c1) v0.16.1rc2 (#2272) (@ascott)
|
||||
- [6e1901e](https://github.com/airbnb/superset/commit/6e1901e8e83d9e2a6e5fc20e3f8e3e996e1ea712) d is not defined, fix (#2270) (@ascott)
|
||||
- [8758296](https://github.com/airbnb/superset/commit/87582962d98424050ff6f61794fd42fe1f5c0c2f) [Hotfix] access slice_id when slice exists (#2268) (@vera-liu)
|
||||
- [3de2698](https://github.com/airbnb/superset/commit/3de2698657b389476a9778754fcbc6fb5acc6853) Introducing support for pre-depercate_v1 URL scheme (#2267) (@mistercrunch)
|
||||
- [ec1f022](https://github.com/airbnb/superset/commit/ec1f0221cd48bb168d0280f55082832d73583f04) Parse filter values for possible integers and floats (#2263) (@vera-liu)
|
||||
- [4d900c9](https://github.com/airbnb/superset/commit/4d900c9ee1e2ab2db0bf42a2c14268cf4ce91186) Do not add slice_name when slice doesn't exist (#2265) (@vera-liu)
|
||||
- [3a75890](https://github.com/airbnb/superset/commit/3a758900eb295039c52be89ecfc13e1260c9b1da) [hotfix] separator renders markdown (@mistercrunch)
|
||||
- [1ea7178](https://github.com/airbnb/superset/commit/1ea7178d17c5b2459e36d213611abcaac0b05620) v0.16.1rc1 (#2260) (@ascott)
|
||||
- [c85c998](https://github.com/airbnb/superset/commit/c85c9988df3d4bba2a9bce36ebfa681225400e42) fix index error for bar charts (#2258) (@ascott)
|
||||
- [34f6807](https://github.com/airbnb/superset/commit/34f68073a28d3dacc4162df7c0e2421cb527afe1) Default action to overwrite for users with overwrite permissions (#2257) (@vera-liu)
|
||||
|
||||
### 0.16.1 (2017/02/24 18:56 +00:00)
|
||||
- [acc880c](https://github.com/airbnb/superset/commit/acc880c4dfc2a02b8d46249895259961e2574c42) [v0.16.1] bump version for prod release (#2250) (@ascott)
|
||||
- [557b557](https://github.com/airbnb/superset/commit/557b557503b1835412337a4d0d4a574535133ec1) [bugfix] avoid caching errors (#2244) (@mistercrunch)
|
||||
- [3018356](https://github.com/airbnb/superset/commit/301835658838fc0d9cb2d807ee8fa06b0ed44550) Support more druid postaggregations. (#2235) (@bkyryliuk)
|
||||
- [ede4dff](https://github.com/airbnb/superset/commit/ede4dffcb71f6d31f9c062af4bcdeeaa9d4ca252) Add trailing slash (#2236) (@bkyryliuk)
|
||||
- [cad392e](https://github.com/airbnb/superset/commit/cad392eb768e65f11b664ad1e2aeffa9741e1bd4) Fetch schemas separately. (#2227) (@bkyryliuk)
|
||||
- [0296158](https://github.com/airbnb/superset/commit/02961581005ddb3abea89b38b1cce6af9247b8db) [docs] more specific about python versions (@mistercrunch)
|
||||
- [b2a4692](https://github.com/airbnb/superset/commit/b2a4692a02a2e6864aa1a8c66f7f63502be3e40e) 0.16.0rc3 (@mistercrunch)
|
||||
- [2fbadea](https://github.com/airbnb/superset/commit/2fbadea9e328554312742d7a8259d7f773ad314a) Fixing exploring a table (#2233) (@mistercrunch)
|
||||
- [dc05be3](https://github.com/airbnb/superset/commit/dc05be36a60237c930ca60184bbbc054182eeab1) Check if the query is in state first. (#2226) (@bkyryliuk)
|
||||
- [dac0d1d](https://github.com/airbnb/superset/commit/dac0d1d0dce2f5ab0c1d5b43814773688ef033c3) 0.16.0rc2 (@mistercrunch)
|
||||
- [459f716](https://github.com/airbnb/superset/commit/459f7160ac7587f92c8213b496fb64518329c1be) Fixing filtering issues (#2223) (@mistercrunch)
|
||||
- [aff524d](https://github.com/airbnb/superset/commit/aff524d84389b605e2f390350f4608f12ed67241) **Allow user to put dbname in url (#2209) (@vera-liu)
|
||||
- [3a91667](https://github.com/airbnb/superset/commit/3a91667e92e0b3bbadd0df4d35d03558268fb6d3) Update cache for the command line command. (#2213) (@bkyryliuk)
|
||||
- [3e0d358](https://github.com/airbnb/superset/commit/3e0d3584f77b2f493687c1c61af63fb4f321bd36) v0.16.0rc1 (@mistercrunch)
|
||||
- [1e47d6f](https://github.com/airbnb/superset/commit/1e47d6fb41b8095e2ab24704c8340c16cf8c13e6) Renaming field to control (#2210) (@mistercrunch)
|
||||
- [d5ba88b](https://github.com/airbnb/superset/commit/d5ba88b4072d45efbb82cc6492645627560794c1) Fixing the CACHING (#2203) (@mistercrunch)
|
||||
- [#2202](https://github.com/airbnb/superset/pull/2202) Merge pull request #2202 from mistercrunch/clean_cli (@mistercrunch)
|
||||
- [ec84aa7](https://github.com/airbnb/superset/commit/ec84aa75770b8a6c8f40f6519596571a5dfb48b5) Fixing typo (@mistercrunch)
|
||||
- [8b4d72c](https://github.com/airbnb/superset/commit/8b4d72cf32fbaa05a196995246090907e197bf7f) Reverting react-select to rc2 (@mistercrunch)
|
||||
- [85e6e65](https://github.com/airbnb/superset/commit/85e6e65a47e5d419b181876f2659038461b24974) Fixing the build (@mistercrunch)
|
||||
- [7cad365](https://github.com/airbnb/superset/commit/7cad3655f5f0638acc76e2a0396baeb28702906a) Bumping react-select to 1.0.0-rc.3 (@mistercrunch)
|
||||
- [b9e7f29](https://github.com/airbnb/superset/commit/b9e7f292c38610a23b75b57cf2ba04d1722fa94f) Cleaning up CLI stdout on startup (@mistercrunch)
|
||||
- [fc85034](https://github.com/airbnb/superset/commit/fc85034c60422d3b504e039e6af87dfd2608d12a) Better error handling for presto (#2161) (@vera-liu)
|
||||
- [f5e3d0c](https://github.com/airbnb/superset/commit/f5e3d0cc02628a51178001eecb65eaa6f04ec667) [hotfix] incompatible diamond flask-sqlalchemy version (@mistercrunch)
|
||||
- [fe377e8](https://github.com/airbnb/superset/commit/fe377e8b9472cc6d16cb2034c2876c758df7ba34) [hotfix] dashboard won't load, error in fields.js (@mistercrunch)
|
||||
- [5bb8713](https://github.com/airbnb/superset/commit/5bb87138e95a07f604e5b82dbac460b6ece06a40) [hotfix] Trends example slice is broken (@mistercrunch)
|
||||
- [579e582](https://github.com/airbnb/superset/commit/579e58206e16b53e49fc736569d6d4ab4e234f70) Bumping up some of the python lib deps (@mistercrunch)
|
||||
|
||||
### 0.16.0 (2017/02/17 01:48 +00:00)
|
||||
- [172b6ce](https://github.com/airbnb/superset/commit/172b6ce8920f79a78e19d49197864ac72ea6647a) v0.16.0 (@mistercrunch)
|
||||
- [0cc8eff](https://github.com/airbnb/superset/commit/0cc8eff1c3f4296bccf495c9deba01eb73b72b83) [WiP] Deprecate Explore v1 (#2064) (@mistercrunch)
|
||||
- [3b023e5](https://github.com/airbnb/superset/commit/3b023e5eaa7e5a4be7957a2a48a90672d2c65e71) add css to the data object to be saved (#2188) (@ascott)
|
||||
- [615d8f1](https://github.com/airbnb/superset/commit/615d8f1624d890f6ce0d5bfe7469394a9245759b) Moving branding assets to folder (@mistercrunch)
|
||||
- [b4409ac](https://github.com/airbnb/superset/commit/b4409ace2171158350ac6243e6b72bce6f89a864) Adding branding assets in the repo (@mistercrunch)
|
||||
- [dbee6ac](https://github.com/airbnb/superset/commit/dbee6aca1fbe2d48c685b3976acbb8dfff3f0624) use pre-wrap for long lines (#2181) (@ascott)
|
||||
- [acfe62e](https://github.com/airbnb/superset/commit/acfe62eaf793da4711a90cdb69aa6ec1ea292447) Add command to refresh datasources (#2180) (@bkyryliuk)
|
||||
- [527a8af](https://github.com/airbnb/superset/commit/527a8af060798c014cde0f9b32d31a2e6540dd57) Return original state for query if query was stopped (#2164) (@vera-liu)
|
||||
- [a5a931a](https://github.com/airbnb/superset/commit/a5a931a670871a9d6f1db9310512c5a064f005a0) Fix werkzeug instance was created twice in Debug Mode (#2135) (#2136) (@asdf2014)
|
||||
- [2f05efa](https://github.com/airbnb/superset/commit/2f05efaf121f6bbcd091f88630115a7e006717c4) Set default time range of query search to the past month (#2162) (@vera-liu)
|
||||
- [83ef8a2](https://github.com/airbnb/superset/commit/83ef8a2e1274ba57f1a64e5e71c94b021da4d933) Add parsing for nested json objects in resultset (#2163) (@vera-liu)
|
||||
- [c564881](https://github.com/airbnb/superset/commit/c564881867abcda7b8dc354e6e2205371ab0a97c) Implement caching and dynamic data fetching. (#1466) (@bkyryliuk)
|
||||
- [b16930f](https://github.com/airbnb/superset/commit/b16930f35dbba1a7d5e3a625dfb4a181cc3aa182) Keep order of axis data when storing df (#2092) (@vera-liu)
|
||||
- [2d910e3](https://github.com/airbnb/superset/commit/2d910e3f07b1e86efba69c6d8e07dbdb5f63ce37) [vis] render line breaks in TableViz (#2118) (@ascott)
|
||||
- [daa1420](https://github.com/airbnb/superset/commit/daa1420c8ec31a813d836474e3e2b04c4db54ab7) adding tests for #1131 (#1902) (@SalehHindi)
|
||||
- [cea310e](https://github.com/airbnb/superset/commit/cea310e50b61f3c8c37d86207dd982d35ba19e28) Using the time zone with specific name for querying Druid (#2143) (@asdf2014)
|
||||
- [fcdd5c6](https://github.com/airbnb/superset/commit/fcdd5c67523a81ffc6db68dbe27d13deb00b6084) [slices axis] fix axis spacing on dashboard and explore slices (#2145) (@ascott)
|
||||
- [2ace73e](https://github.com/airbnb/superset/commit/2ace73e9a1f1cf1a20eff632d08ea440f5f88607) [sql-lab] make datasource name in visualize flow more descriptive (#2103) (@ascott)
|
||||
- [80cfb08](https://github.com/airbnb/superset/commit/80cfb08794d3c8d91514f9b7731b057664628cf3) only call drawGraph once (#2132) (@ascott)
|
||||
- [1edc2b9](https://github.com/airbnb/superset/commit/1edc2b91cf15f669097939c36c6bc8acef5b5913) Fix ExtDeprecationWarning (#2137) (#2138) (@asdf2014)
|
||||
- [1f58e18](https://github.com/airbnb/superset/commit/1f58e18b6f134e2ad4c6865c6b63b40135889ebc) Some code refactoring (#2139) (@asdf2014)
|
||||
- [f2bf316](https://github.com/airbnb/superset/commit/f2bf3160583533bd0dc5004f248f81251aa8c57e) Add NUMERIC num_type (#2127) (@auxsvr)
|
||||
- [9cd38fa](https://github.com/airbnb/superset/commit/9cd38fa1eda63152c27b76c29dd948f29444b686) little code refactor in models.py (#2124) (@asdf2014)
|
||||
- [edb0111](https://github.com/airbnb/superset/commit/edb0111775a05ed164019246ee3d7764a9fdba67) Increase query limit to 1M, add separate display limit. (#2111) (@bkyryliuk)
|
||||
- [#2113](https://github.com/airbnb/superset/pull/2113) Merge pull request #2113 from airbnb/byolken/s3_cache_implementation (@airbnb)
|
||||
- [461e41c](https://github.com/airbnb/superset/commit/461e41cd610d1bff33ac10c6ea5879b498a16f41) Use BytesIO instead of StringIO for python2/3 compatibility
|
||||
- [7164061](https://github.com/airbnb/superset/commit/716406198e50b04d2f6600c518b01f65ad690748) Clean up imports of cPickle and StringIO
|
||||
- [68592ae](https://github.com/airbnb/superset/commit/68592aeddfdd88a2cb291533a9e595cff9b5d6d2) Fix StringIO import in results_backends module
|
||||
- [b927ff6](https://github.com/airbnb/superset/commit/b927ff6eef7e948be1f2a7e828f0d7de9458d2c2) Fix indentation errors in results_backends module
|
||||
- [ce50e6e](https://github.com/airbnb/superset/commit/ce50e6e4fe2147cdf61288d687d49e174f3b7b1d) Fix python3 cPickle import errors
|
||||
- [167ed33](https://github.com/airbnb/superset/commit/167ed33bba160f091e613bc2a351ca5ddc7c8189) Fix name of test in results_backends_tests module
|
||||
- [0ee1abf](https://github.com/airbnb/superset/commit/0ee1abf31a021d2c9e40d9b3c321fce14d4d7179) Misc. fixes in response to code review feedback
|
||||
- [6a0a1af](https://github.com/airbnb/superset/commit/6a0a1af67ebfc11fde51eb3d77db7b9ac6569c3c) Fix misc. style issues
|
||||
- [f85481d](https://github.com/airbnb/superset/commit/f85481d51b3481d7e0ee7f9b73991fb5e2b219ef) Fix long lines in superset/results_backends.py
|
||||
- [00b6b0a](https://github.com/airbnb/superset/commit/00b6b0ac68571df1a7c8e16fd0e79c64cbfe0a60) Misc. style tweaks to S3Cache changes and tests
|
||||
- [1546b1a](https://github.com/airbnb/superset/commit/1546b1ae716d47dad7c583100dbf73665d88aa3b) Add tests for S3Cache
|
||||
- [1e94498](https://github.com/airbnb/superset/commit/1e94498d9d548cbea6466a45dafa3b919c65bd1f) Add initial implementation of S3Cache
|
||||
- [0f7189b](https://github.com/airbnb/superset/commit/0f7189b859f4a782fd43af694012029645f81b44) Do not fail is the filter cannot be parsed. (#2105) (@bkyryliuk)
|
||||
- [a6e0f1b](https://github.com/airbnb/superset/commit/a6e0f1b75a5b60dbb81288b22d78d9686c3b565c) Add an option to configure celery workers size. (#2085) (@bkyryliuk)
|
||||
- [543c22b](https://github.com/airbnb/superset/commit/543c22bb508a90741ff770e50670b412a45e1871) [dashboard] fix nvd3 tooltips (#2096) (@ascott)
|
||||
- [07e067c](https://github.com/airbnb/superset/commit/07e067cf0b8fae39e5e7093914f0fc1795b15f41) Revert "Bump version to 0.15.4.1" (#2095) (@bkyryliuk)
|
||||
- [6c256a3](https://github.com/airbnb/superset/commit/6c256a34a98a9323f1044b138c458d5c60e0e01f) Bump version to 0.15.4.1 (#2094) (@bkyryliuk)
|
||||
- [6b2eb04](https://github.com/airbnb/superset/commit/6b2eb04a73a475b1d597076b15bc39c5e0156842) Put back a default count * metric (#2091) (@bkyryliuk)
|
||||
- [898d80b](https://github.com/airbnb/superset/commit/898d80ba3837b44c00092f9339fc0ba25efc3162) Viz the compiled query rather than user input. (#2086) (@bkyryliuk)
|
||||
- [ea8e4ad](https://github.com/airbnb/superset/commit/ea8e4ad05b7298db023c3cfb5079dff92a5da1d3) Display all columns if none are specified. (#2077) (@bkyryliuk)
|
||||
- [27aeac6](https://github.com/airbnb/superset/commit/27aeac6859da39fea0aebc4920c1fce08fde61e5) Remove fetch results button for async queries (#2084) (@vera-liu)
|
||||
- [8da371e](https://github.com/airbnb/superset/commit/8da371e324e490bec74d80eb84ca040c86dd6765) Make show query button work for v1 (#2080) (@vera-liu)
|
||||
- [0c59fe9](https://github.com/airbnb/superset/commit/0c59fe933d0012eb63acfa02bb51273327b4e218) Only call topn when having_filters don't exist (#2075) (@vera-liu)
|
||||
- [e169c67](https://github.com/airbnb/superset/commit/e169c67760b8ef3b0cafa3eebaf17ea662589ea4) [vis] fix axis labels display (#2066) (@ascott)
|
||||
- [3a5a927](https://github.com/airbnb/superset/commit/3a5a927dc6e43fe095a0b5592505cea09c42f5e4) check if tempTable exists for ctas queries (#2073) (@vera-liu)
|
||||
- [2d419e4](https://github.com/airbnb/superset/commit/2d419e4253c8a8874c1a913b4193402c3a4e0187) Return alert instead of fetch button when async results has no data (#2072) (@vera-liu)
|
||||
- [87869a2](https://github.com/airbnb/superset/commit/87869a29c98b3fadbe1d6879437530f5623d774f) Customize tooltip with axis format (#2068) (@vera-liu)
|
||||
- [544211f](https://github.com/airbnb/superset/commit/544211f5ecbe63958de72bcc014bc4de23f30bb7) Revert "Display no data alert when async result has zero rows" (#2069) (@vera-liu)
|
||||
- [f6ac95e](https://github.com/airbnb/superset/commit/f6ac95e2dd14eff2ba6c86cc1512a88992e18538) Convert objects to json (#2050) (@bkyryliuk)
|
||||
- [63bef2f](https://github.com/airbnb/superset/commit/63bef2f8440620407b6dfe9ebadf8305450fce28) [bugfix] only pop slice_id when it exists in url (#2065) (@vera-liu)
|
||||
- [4a8cd04](https://github.com/airbnb/superset/commit/4a8cd04de6f1fd6aea060ee62968903dc3892fb8) Display no data when async result has zero rows (#2055) (@vera-liu)
|
||||
- [8580662](https://github.com/airbnb/superset/commit/85806624db3d4651bc9d1b15e32b34c9d644cfdd) Use a key-value store model for sharing long queries (#1951) (@vera-liu)
|
||||
- [1ac2273](https://github.com/airbnb/superset/commit/1ac22739848fef09b663ca3fbad9bf84eb706211) Reimplement has_access. (#2028) (@bkyryliuk)
|
||||
- [a8c29c4](https://github.com/airbnb/superset/commit/a8c29c4ffec1bcf631cea0afbb40e95a4817cf07) Change validator of timeshift to allow for strings (#2051) (@vera-liu)
|
||||
- [31af01c](https://github.com/airbnb/superset/commit/31af01c4f2b54c05a0f4bc66c7fcaaa9fe0b0681) Splitting dev-reqs.txt into requirements for development and docs (dev-reqs-for-docs.txt). Updating CONTRIBUTING.md accordingly (#2049) (@dylburger)
|
||||
- [b1bba96](https://github.com/airbnb/superset/commit/b1bba96d04b636d77d557ca066e22d3f2bd3289b) Fix csv download. (#2036) (@bkyryliuk)
|
||||
- [c5c7302](https://github.com/airbnb/superset/commit/c5c730224e6ab89cfbffb26f1c9a1fc0429e2299) Check datasource level perms for downloading csv and fetching results (#2032) (@bkyryliuk)
|
||||
- [7441cf7](https://github.com/airbnb/superset/commit/7441cf7d39ffcdab4def1c9b098203610a067794) Fix inner query labels for Vertica (#2041) (@0x0ece)
|
||||
- [45c72d2](https://github.com/airbnb/superset/commit/45c72d25df68dfceb1bcf5d305700c0972d48407) New administrator tutorial (#2046) (@dylburger)
|
||||
- [3fff631](https://github.com/airbnb/superset/commit/3fff631b32579ed1d3fa5b50349542b83dc62fda) Expanded on documentation section, running through an example of committing a change to the docs end-to-end and describing the process for adding static assets (#2047) (@dylburger)
|
||||
- [bfa2891](https://github.com/airbnb/superset/commit/bfa2891b23426740836226be31e160f0d6e132ae) models: add real to numeric types (#2044) (@xrmx)
|
||||
- [5715f52](https://github.com/airbnb/superset/commit/5715f52fef633473d5e7e1d554a7be97c0840fa8) [hotfix] delete DAR when datasource requested does not exist anymore (#2040) (@vera-liu)
|
||||
- [1f2126f](https://github.com/airbnb/superset/commit/1f2126f4637d6099bb1591f4c7715bd3c4385878) Fix Druid granularity timeZone (#2037) (@0x0ece)
|
||||
- [27ed0b3](https://github.com/airbnb/superset/commit/27ed0b37bf3291a688124be5687738ecb37fa8b3) Cleanup fulfilled requests after approve (#1953) (@vera-liu)
|
||||
- [cdbd2f8](https://github.com/airbnb/superset/commit/cdbd2f850706825f16a08afc40682237d6f6d54f) Guess the filter value type (#1978) (@bkyryliuk)
|
||||
- [e46ba2b](https://github.com/airbnb/superset/commit/e46ba2b4a4f5ccc9f584db0a3c7c1fbaf2b7fdf0) Simplifying the viz interface (#2005) (@mistercrunch)
|
||||
- [1c338ba](https://github.com/airbnb/superset/commit/1c338ba742108139c3fe5885765633f298734be5) [WIP] [explorev2] Refactor filter into FieldSet (#1981) (@vera-liu)
|
||||
- [2b7673a](https://github.com/airbnb/superset/commit/2b7673ad5d95f63b3e251f08f6141f82447d0e23) Fixing pypi_push.sh (@mistercrunch)
|
||||
|
||||
### 0.15.4 (2017/01/24 19:33 +00:00)
|
||||
- [2f27353](https://github.com/airbnb/superset/commit/2f27353015e18a1eab8ca415131023e91adf5399) v0.15.4 (@mistercrunch)
|
||||
- [1b8c3f4](https://github.com/airbnb/superset/commit/1b8c3f420a6f74fa8dd6e5a0762e14d9ba5f7426) avoid py3 error in setup.py (#2030) (@wyndhblb)
|
||||
- [a3a0708](https://github.com/airbnb/superset/commit/a3a070855ccea84e75f89389c835772bbde66d10) Use dist instead of src in mapbox (#2027) (@0x0ece)
|
||||
- [e84c639](https://github.com/airbnb/superset/commit/e84c6393b8658c7e8d9b321c08f0dea33335aa28) Correcting docs to `run npm build` instead of prod (@mistercrunch)
|
||||
|
||||
### 0.15.3 (2017/01/24 16:10 +00:00)
|
||||
- [7413dd9](https://github.com/airbnb/superset/commit/7413dd9f4b99752d064024e764284beabb82a3cc) v0.15.3 (@mistercrunch)
|
||||
- [9cbd667](https://github.com/airbnb/superset/commit/9cbd667eb7af96cb2cafaf05778906110cf50520) [explore-v2] Fix edit datasource link for druid datasources (#1982) (@ascott)
|
||||
- [37fb56c](https://github.com/airbnb/superset/commit/37fb56c61ceb339079ff117971fc91bdd678db80) Week beginning Monday time grain for MySQL (#2014) (@alanmcruickshank)
|
||||
- [404a94c](https://github.com/airbnb/superset/commit/404a94cadbe44a463bda2201b22f268201a7474c) [hotfix] fixing the hotfix (@mistercrunch)
|
||||
- [0807a8d](https://github.com/airbnb/superset/commit/0807a8d0162ff824151df70e7d045f9179668ac0) [hotfix] load selectors in render (@mistercrunch)
|
||||
- [4a98881](https://github.com/airbnb/superset/commit/4a9888157ebcd8513c083f381fdb417fc5f700de) Update INTHEWILD.md (#2000) (@silashundt)
|
||||
- [83fbdcc](https://github.com/airbnb/superset/commit/83fbdcceac0c5ee836345ff6b0fe03b1c2c6d69f) Add Qunar to INTHEWILD (#2001) (@flametest)
|
||||
- [b070ef5](https://github.com/airbnb/superset/commit/b070ef5fdb2ce61b288362878cfd7622d6e1270c) added Digit to inthewild (#1997) (@robert-digit)
|
||||
- [7d380dc](https://github.com/airbnb/superset/commit/7d380dcd14939f8100405f9f1551a3e2a74054ce) Adding Clark.de and Yahoo to INTHEWILD (@mistercrunch)
|
||||
- [a15dbd9](https://github.com/airbnb/superset/commit/a15dbd992d53870280700e6dd15f604bd76aa4fc) Adding Clark.de to INTHEWILD (@mistercrunch)
|
||||
- [52c5d23](https://github.com/airbnb/superset/commit/52c5d235af43f659a36ddd0baeece95756395f1b) Add analysisTypes to refresh druid (#1983) (@noppanit)
|
||||
- [495f646](https://github.com/airbnb/superset/commit/495f6460a40f4a2622f52c03f511778c4060b1f5) Add email functionality (#1914) (@bkyryliuk)
|
||||
- [a96024d](https://github.com/airbnb/superset/commit/a96024d0e7c54e5559205beb4f770db1e0ff85bb) [explorev2] Fields can validate input and handle errors (#1980) (@mistercrunch)
|
||||
- [99b84d2](https://github.com/airbnb/superset/commit/99b84d29091fcbdd233c91cc239cc6d2cf4b2e74) Reverting CLI changes in #1713 (#1964) (@mistercrunch)
|
||||
- [24728b8](https://github.com/airbnb/superset/commit/24728b8b47037ba809be95e759dc73ce7a8f73a5) Permissions cleanup: remove none and duplicates. (#1967) (@bkyryliuk)
|
||||
- [9750e49](https://github.com/airbnb/superset/commit/9750e49df8ff95d9dcbd25bea426eaa1ddcb67bd) Add the missing argument (#1969) (@flametest)
|
||||
- [bf31783](https://github.com/airbnb/superset/commit/bf31783d0ccc62712800ed3cc7caf63890ba36b5) v0.15.2 (@ascott)
|
||||
|
||||
### 0.15.2 (2017/01/13 07:05 +00:00)
|
||||
- [87eacf8](https://github.com/airbnb/superset/commit/87eacf88c3ee82f6fe3cf79c54672f6c64b7f3fb) fix timestamp error in table view (#1960) (@flametest)
|
||||
- [1dbfb99](https://github.com/airbnb/superset/commit/1dbfb99ead4be6669752853e58504b0f0eab351d) Leave metrics empty if not specified (#1965) (@vera-liu)
|
||||
- [ff4020e](https://github.com/airbnb/superset/commit/ff4020ea732de873feb82d94971cadcc5d5c0e74) [explorev2] using label in 'Visualization Type' Select instead of key (#1927) (@mistercrunch)
|
||||
- [0ce7fc1](https://github.com/airbnb/superset/commit/0ce7fc18a883af3ba9d35a498912fcf49ab1e70c) Adding a way to see the git SHA from the website (#1956) (@mistercrunch)
|
||||
- [470a6e9](https://github.com/airbnb/superset/commit/470a6e9d768493e7f9671d3cbe436e03ff15f137) [explorev2] adding support for client side validators on controls (#1920) (@mistercrunch)
|
||||
- [fc74fbe](https://github.com/airbnb/superset/commit/fc74fbeeaa0834f1dcf5f83b25d3b709b1b9fd95) [explore-v2] make control panel sections and fields more dense (#1954) (@ascott)
|
||||
- [9c6a579](https://github.com/airbnb/superset/commit/9c6a5793b9841686c483f818f9ef1af4cf0b9b73) Fix none view_menues. (#1950) (@bkyryliuk)
|
||||
- [49b6b38](https://github.com/airbnb/superset/commit/49b6b387410987ef19da36118fc06b4a52d69c85) Pass query instead of slice to Action buttons to prevent lagging query (#1948) (@vera-liu)
|
||||
- [a385ee9](https://github.com/airbnb/superset/commit/a385ee9e978c1175f95b3704669ab70489469860) Use POST in sqllab_viz instead of url params to avoid error with long queries (#1933) (@vera-liu)
|
||||
- [f0917c6](https://github.com/airbnb/superset/commit/f0917c62f20e5f1a36e3fa99f155787ff5e54afd) Add a Async Select that fetches options from given endpoint (#1909) (@vera-liu)
|
||||
- [94d2016](https://github.com/airbnb/superset/commit/94d20168dab4b85fc3f2d2172a2ae899de5aa2ba) Change fields for dual_line to match with new SelectField structure (#1932) (@vera-liu)
|
||||
- [2d866e3](https://github.com/airbnb/superset/commit/2d866e3ffa9bfedd3b3dad0d3463767aae879a14) [hotfix] fix the logging fix that broke the build (#1940) (@mistercrunch)
|
||||
- [5d94d70](https://github.com/airbnb/superset/commit/5d94d7067e3cc052f27c736c46a0d74c270ca387) [explore-v2] add edit link below datasource select (#1919) (@ascott)
|
||||
- [7323f4c](https://github.com/airbnb/superset/commit/7323f4c2ab2eda54e91274a6e9281f0a98160850) Make up the user link string (#1947) (@flametest)
|
||||
- [eca6dfe](https://github.com/airbnb/superset/commit/eca6dfef6afa05929fa240177e389e6c9a989aaf) switch order of period compare and rolling periods (#1946) (@patrickleotardif)
|
||||
- [761462e](https://github.com/airbnb/superset/commit/761462ef930fa8ac1094629b403d0ec09bb5c0ab) Revert "#views users for created dashboards on profile page" (#1943) (@vera-liu)
|
||||
- [98e8325](https://github.com/airbnb/superset/commit/98e83255e6efa18b72b7b17413d55d49ee9213b9) Added extra details around setting up admin user (#1937) (@mobcdi)
|
||||
- [cbf3562](https://github.com/airbnb/superset/commit/cbf3562a6f4d2edaaf14592c0bee6cab8394108c) Fix double scrollbar in pivot table (UI bug) (#1931) (@SalehHindi)
|
||||
- [a2c41bb](https://github.com/airbnb/superset/commit/a2c41bbace99eb3e749c59a3b2805c6e8e2b7130) viz: hotfix for saving in cache (#1922) (@xrmx)
|
||||
- [2a12a3c](https://github.com/airbnb/superset/commit/2a12a3c70267987c4bc3ecfad08aba4a5769fa10) [hotfix] logging is down (@mistercrunch)
|
||||
- [2ab6a41](https://github.com/airbnb/superset/commit/2ab6a411f4b9fa75bc86b83f4aa4e3707e90e002) Druid dashboard import/export. (#1930) (@bkyryliuk)
|
||||
- [14ed10b](https://github.com/airbnb/superset/commit/14ed10bdb0f6868e87c8cf39d770fcc616273e72) Fixing docs generation (@mistercrunch)
|
||||
- [49e6fd5](https://github.com/airbnb/superset/commit/49e6fd5bfbdb90020bf821f843a7e850e70a4c6b) Revert "Druid dashboard import/export. " (#1923) (@mistercrunch)
|
||||
- [af872fa](https://github.com/airbnb/superset/commit/af872fa4d4fbafb29bf47418c7c2b6716846f509) Druid dashboard import/export. (#1811) (@bkyryliuk)
|
||||
- [cec4cf0](https://github.com/airbnb/superset/commit/cec4cf014c91e5b664cc3dbfba34619388fd492e) #views users for created dashboards on profile page (#1667) (@vera-liu)
|
||||
- [783ad70](https://github.com/airbnb/superset/commit/783ad703d06a1e3b75c76307174af02d843cda0d) [hotfix] delete ipdb breakpoint (#1917) (@vera-liu)
|
||||
- [2226716](https://github.com/airbnb/superset/commit/222671675c31bdad9b8e2c8f3a5b814a02d85bee) [exploreV2] mapStateToProps for fields (#1882) (@mistercrunch)
|
||||
- [9a62d94](https://github.com/airbnb/superset/commit/9a62d9463005631f2d43b57a0d782453db98931e) [sqllab] bugfix visualizing a query with a semi-colon (#1869) (@mistercrunch)
|
||||
- [c3edc6e](https://github.com/airbnb/superset/commit/c3edc6e24bb55dcf26d29603b624ba513a562232) [WIP] Add dual-axis line chart to viz (#1782) (@vera-liu)
|
||||
- [119b0c5](https://github.com/airbnb/superset/commit/119b0c55e972d4b4b93ff9df4d7e99d14b9b8453) [explore] fix height in embed mode (#1898) (@mistercrunch)
|
||||
- [c14c7ed](https://github.com/airbnb/superset/commit/c14c7edc5ee798eb24b53ae65fec9a876fbe1fd9) [explore] show the broken query when failing (#1871) (@mistercrunch)
|
||||
- [e3b296c](https://github.com/airbnb/superset/commit/e3b296c558dcad4f77b6c82c37ed20903b1699bf) utils: teach our json serializer to handle more types (#1907) (@xrmx)
|
||||
- [c2d29fb](https://github.com/airbnb/superset/commit/c2d29fb54bbe8e57bdee03f4f4940469b48c2a92) Change ordering of fields when adding a table (#1899) (@mistercrunch)
|
||||
- [7aab8b0](https://github.com/airbnb/superset/commit/7aab8b0ae3d6816cf861c09193c9e2e166e2d18a) Simplifying the Fields (Controls) interface (#1868) (@mistercrunch)
|
||||
- [861a3bd](https://github.com/airbnb/superset/commit/861a3bd4ae85da2bb227c3d44a4ff56b9a836caf) docs: 8088 is the default port, no need to specify it (#1861) (@andreamelloncelli)
|
||||
- [9bc7ad9](https://github.com/airbnb/superset/commit/9bc7ad9cd53b9204a044c5dff16185ca49bd66a4) Do not use persistState for explorev2 (#1894) (@vera-liu)
|
||||
- [a1e3fc1](https://github.com/airbnb/superset/commit/a1e3fc1c230239c5535573cf708ff0e03d5eaa8a) [explorev2] giving more room for long textboxes (#1881) (@mistercrunch)
|
||||
- [242869d](https://github.com/airbnb/superset/commit/242869db3aa8eab99558d19f0e99923a78fb9840) [sql lab] only show single run query button (#1858) (@ascott)
|
||||
- [8924bb7](https://github.com/airbnb/superset/commit/8924bb79e74704632cc4401f0ed1f7134be11a1d) [explorev2] moving the "Time" section up to 2nd section (#1885) (@mistercrunch)
|
||||
- [a0d103d](https://github.com/airbnb/superset/commit/a0d103dac33201b55b2587d10d11f293bed0a0e7) Fix small typo (#1888) (@davejm)
|
||||
- [d52b299](https://github.com/airbnb/superset/commit/d52b299df8812ff4af5fb05ded2c1b3aedaae865) Updating CHANGELOG (@mistercrunch)
|
||||
|
||||
### 0.15.1 (2016/12/28 21:29 +00:00)
|
||||
- [092432f](https://github.com/airbnb/superset/commit/092432f04f0033e60493f009728a7bfd6a744b22) v0.15.1 (@mistercrunch)
|
||||
- [ea8e663](https://github.com/airbnb/superset/commit/ea8e6634d6c304cde3a42c65d37ec694f76b8cec) read anon user role from config, remove reference to public role (#1878) (@willgroves)
|
||||
@@ -11,7 +318,6 @@
|
||||
- [bb04e6f](https://github.com/airbnb/superset/commit/bb04e6fcfa1042b4532b50d8898555813be7fa29) Use APP_ICON in template (#1855) (@szmate1618)
|
||||
- [007ee88](https://github.com/airbnb/superset/commit/007ee88d33f92e6d052122b35ccad84d176029a7) [explorev2] improving the scrolling/scrollbars placement (#1840) (@mistercrunch)
|
||||
|
||||
### airbnb_prod.0.15.0.1 (2016/12/15 22:06 +00:00)
|
||||
- [7a5bb94](https://github.com/airbnb/superset/commit/7a5bb947542fdc20e2ec70e18b1cf418b8d1dba8) Stop ChartContainer from rendering twice on chartStatus change (#1828) (@vera-liu)
|
||||
- [e06a0cd](https://github.com/airbnb/superset/commit/e06a0cd89bc84f3a7e75ee6f03df8c9c3a2badeb) Add force_ctas_schema to query model when enabled (#1825) (@vera-liu)
|
||||
- [b6cba13](https://github.com/airbnb/superset/commit/b6cba13293101f3022c16e120e96383b59cae03e) [explorev2] enabling redux dev tools (#1842) (@mistercrunch)
|
||||
@@ -46,10 +352,8 @@
|
||||
- [74edb93](https://github.com/airbnb/superset/commit/74edb936a599ed54528389814ddf83e74f8452fd) [WIP] Add http to copied url and move function to componentWillReceiveProps (#1780) (@vera-liu)
|
||||
- [c155857](https://github.com/airbnb/superset/commit/c1558578d7c555fb7bb9ee30eb98bad4d28fbd07) [explorev2] Breaking down large files, fixing JS warnings (#1773) (@mistercrunch)
|
||||
|
||||
### airbnb_prod.0.13.0.3 (2016/12/06 07:18 +00:00)
|
||||
- [3597fdb](https://github.com/airbnb/superset/commit/3597fdb7f869929e0b09ff0144ff430b81e67853) Filter table list based on the user permissions. (#1769) (@bkyryliuk)
|
||||
|
||||
### airbnb_prod.0.13.0.2 (2016/12/06 01:17 +00:00)
|
||||
- [43f2a37](https://github.com/airbnb/superset/commit/43f2a379a1b88b260d0a4bdeac97b3cb4478afcf) Make cell-click filter in table viz optional (#1762) (@vera-liu)
|
||||
- [69702e3](https://github.com/airbnb/superset/commit/69702e3a1956ef5587e5aea2bffb3720b9b4cd35) Create users if not found. (#1753) (@bkyryliuk)
|
||||
- [eb0655c](https://github.com/airbnb/superset/commit/eb0655cf85daad4329cf8630fe99e2a50d0e7e5a) [sqllab] Fixed js error when results are not available (#1715) (@vera-liu)
|
||||
@@ -69,8 +373,6 @@
|
||||
- [168a252](https://github.com/airbnb/superset/commit/168a25239e712fe9eccf676f26df75fd91bd126f) State that npm should be between 3.9 and 4 (@bkyryliuk)
|
||||
- [7eef46e](https://github.com/airbnb/superset/commit/7eef46e9413b01ec15be515567a9619c695d5501) Adding links pointing to the new user profile page (#1704) (@mistercrunch)
|
||||
- [50da4f8](https://github.com/airbnb/superset/commit/50da4f8c0708f91ff24c0abd7189a137a1415bf6) Support running superset via pex (#1713) (@yolken)
|
||||
|
||||
### airbnb_prod.0.13.0.1 (2016/12/01 19:59 +00:00)
|
||||
- [2d0ebea](https://github.com/airbnb/superset/commit/2d0ebeae1bfd5e385000c9aa952891cf474821c6) [explorev2] Make chart container more responsive (#1724) (@vera-liu)
|
||||
- [1a16491](https://github.com/airbnb/superset/commit/1a164919715d6eaf1a999b97daaa53acb94a827d) Display full table name (schema + name) if possible. (#1728) (@bkyryliuk)
|
||||
- [7f4f250](https://github.com/airbnb/superset/commit/7f4f25097046dac9b436ef87f041debe2713827a) Redirects to login page if user not logged in at welcome page (#1723) (@vera-liu)
|
||||
@@ -179,7 +481,6 @@
|
||||
- [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)
|
||||
@@ -414,7 +715,6 @@
|
||||
- [508feb2](https://github.com/airbnb/caravel/commit/508feb2bad581068a47193e06d35ed5926b25191) [hotfix] getting presto on track
|
||||
- [9f8eef4](https://github.com/airbnb/caravel/commit/9f8eef498c93ce2945e3d17cda1c3d2a24d05c92) [theme] a little bit less blue (#1024) (@mistercrunch)
|
||||
|
||||
### airbnb_prod.0.10.0.2 (2016/08/30 18:08 +00:00)
|
||||
- [561828c](https://github.com/airbnb/caravel/commit/561828c2f890e179c4116f773cc7507103804dc6) [SQL Lab] moving the db/schema/table select to the left (#1038) (@mistercrunch)
|
||||
- [fc1e637](https://github.com/airbnb/caravel/commit/fc1e63761cc86a5673433b0e2efc0081325684d3) Adding celery_tests.py (@mistercrunch)
|
||||
- [38b8db8](https://github.com/airbnb/caravel/commit/38b8db8051490375d021c51fb76a9f1bdc3ccf1f) SQL Lab - A multi-tab SQL editor (#514) (@mistercrunch)
|
||||
@@ -437,7 +737,6 @@
|
||||
- [c7467f5](https://github.com/airbnb/caravel/commit/c7467f544c10281538b8504add9510f3fcf20e60) Documenting making your own build (#990) (@mistercrunch)
|
||||
- [30ef8eb](https://github.com/airbnb/caravel/commit/30ef8eba37073c2cb0d2a6356fe3a9bcabab4913) [ui] hack bootswatch/cosmo theme to get better tabs for sql-lab (and other things) (#975) (@ascott)
|
||||
|
||||
### airbnb_prod.0.10.0.1 (2016/08/18 07:02 +00:00)
|
||||
- [23a5463](https://github.com/airbnb/caravel/commit/23a54632081aa589e05a820ac774c8b4f6993252) Hack around the "last migration doesn't stamp" Alembic bug (#967) (@mistercrunch)
|
||||
- [84213ab](https://github.com/airbnb/caravel/commit/84213ab8cd27369f796131c68c075f12f8bd0ce2) [line] growth vs factor option for 'Period Ratio' (#970) (@mistercrunch)
|
||||
- [379cf6c](https://github.com/airbnb/caravel/commit/379cf6cbd9527617b6aae60501ad2fa4e252bb8f) [ui] tweaks and improvements (#965) (@ascott)
|
||||
|
||||
@@ -47,9 +47,96 @@ If you are proposing a feature:
|
||||
- Remember that this is a volunteer-driven project, and that
|
||||
contributions are welcome :)
|
||||
|
||||
## Latest Documentation
|
||||
## Documentation
|
||||
|
||||
Latest documentation and tutorial are available [here](http://airbnb.io/superset)
|
||||
The latest documentation and tutorial are available [here](http://airbnb.io/superset).
|
||||
|
||||
Contributing to the official documentation is relatively easy, once you've setup
|
||||
your environment and done an edit end-to-end. The docs can be found in the
|
||||
`docs/` subdirectory of the repository, and are written in the
|
||||
[reStructuredText format](https://en.wikipedia.org/wiki/ReStructuredText) (.rst).
|
||||
If you've written Markdown before, you'll find the reStructuredText format familiar.
|
||||
|
||||
Superset uses [Sphinx](http://www.sphinx-doc.org/en/1.5.1/) to convert the rst files
|
||||
in `docs/` to the final HTML output users see.
|
||||
|
||||
Before you start changing the docs, you'll want to
|
||||
[fork the Superset project on Github](https://help.github.com/articles/fork-a-repo/).
|
||||
Once that new repository has been created, clone it on your local machine:
|
||||
|
||||
git clone git@github.com:your_username/superset.git
|
||||
|
||||
At this point, you may also want to create a
|
||||
[Python virtual environment](http://docs.python-guide.org/en/latest/dev/virtualenvs/)
|
||||
to manage the Python packages you're about to install:
|
||||
|
||||
virtualenv superset-dev
|
||||
source superset-dev/bin/activate
|
||||
|
||||
Finally, to make changes to the rst files and build the docs using Sphinx,
|
||||
you'll need to install a handful of dependencies from the repo you cloned:
|
||||
|
||||
cd superset
|
||||
pip install -r dev-reqs-for-docs.txt
|
||||
|
||||
To get the feel for how to edit and build the docs, let's edit a file, build
|
||||
the docs and see our changes in action. First, you'll want to
|
||||
[create a new branch](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging)
|
||||
to work on your changes:
|
||||
|
||||
git checkout -b changes-to-docs
|
||||
|
||||
Now, go ahead and edit one of the files under `docs/`, say `docs/tutorial.rst`
|
||||
- change it however you want. Check out the
|
||||
[ReStructuredText Primer](http://docutils.sourceforge.net/docs/user/rst/quickstart.html)
|
||||
for a reference on the formatting of the rst files.
|
||||
|
||||
Once you've made your changes, run this command from the root of the Superset
|
||||
repo to convert the docs into HTML:
|
||||
|
||||
python setup.py build_sphinx
|
||||
|
||||
You'll see a lot of output as Sphinx handles the conversion. After it's done, the
|
||||
HTML Sphinx generated should be in `docs/_build/html`. Go ahead and navigate there
|
||||
and start a simple web server so we can check out the docs in a browser:
|
||||
|
||||
cd docs/_build/html
|
||||
python -m SimpleHTTPServer
|
||||
|
||||
This will start a small Python web server listening on port 8000. Point your
|
||||
browser to [http://localhost:8000/](http://localhost:8000/), find the file
|
||||
you edited earlier, and check out your changes!
|
||||
|
||||
If you've made a change you'd like to contribute to the actual docs, just commit
|
||||
your code, push your new branch to Github:
|
||||
|
||||
git add docs/tutorial.rst
|
||||
git commit -m 'Awesome new change to tutorial'
|
||||
git push origin changes-to-docs
|
||||
|
||||
Then, [open a pull request](https://help.github.com/articles/about-pull-requests/).
|
||||
|
||||
If you're adding new images to the documentation, you'll notice that the images
|
||||
referenced in the rst, e.g.
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_01_sources_database.png
|
||||
|
||||
aren't actually included in that directory. _Instead_, you'll want to add and commit
|
||||
images (and any other static assets) to the _superset/assets/images_ directory.
|
||||
When the docs are being pushed to [airbnb.io](http://airbnb.io/superset/), images
|
||||
will be moved from there to the _\_static/img_ directory, just like they're referenced
|
||||
in the docs.
|
||||
|
||||
For example, the image referenced above actually lives in
|
||||
|
||||
superset/assets/images/tutorial
|
||||
|
||||
Since the image is moved during the documentation build process, the docs reference the
|
||||
image in
|
||||
|
||||
_static/img/tutorial
|
||||
|
||||
instead.
|
||||
|
||||
## Setting up a Python development environment
|
||||
|
||||
@@ -124,6 +211,9 @@ following commands. The `dev` flag will keep the npm script running and
|
||||
re-run it upon any changes within the assets directory.
|
||||
|
||||
```
|
||||
# Copies a conf file from the frontend to the backend
|
||||
npm run sync-backend
|
||||
|
||||
# Compiles the production / optimized js & css
|
||||
npm run prod
|
||||
|
||||
|
||||
19
INTHEWILD.md
@@ -4,11 +4,20 @@ to add your organization and/or project to this document!
|
||||
Organizations
|
||||
----------
|
||||
- [Airbnb](https://github.com/airbnb)
|
||||
- [GfK Data Lab] (http://datalab.gfk.com)
|
||||
- [Maieutical Labs] (https://cloudschooling.it)
|
||||
- [Shopkick] (https://www.shopkick.com)
|
||||
- [Amino] (https://amino.com)
|
||||
- [Faasos] (http://faasos.com/)
|
||||
- [GfK Data Lab](http://datalab.gfk.com)
|
||||
- [Maieutical Labs](https://cloudschooling.it)
|
||||
- [Shopkick](https://www.shopkick.com)
|
||||
- [Amino](https://amino.com)
|
||||
- [Faasos](http://faasos.com/)
|
||||
- [Clark.de](http://clark.de/)
|
||||
- [Yahoo!](www.yahoo.com)
|
||||
- [Digit Game Studios](https://www.digitgaming.com/)
|
||||
- [Brilliant.org](https://brilliant.org/)
|
||||
- [Qunar](https://www.qunar.com/)
|
||||
- [Udemy](https://www.udemy.com/)
|
||||
- [Tooploox](https://www.tooploox.com/)
|
||||
- [Tobii](http://www.tobii.com/)
|
||||
- [Endress+Hauser](http://www.endress.com/)
|
||||
|
||||
Projects
|
||||
----------
|
||||
|
||||
@@ -29,17 +29,23 @@ Screenshots & Gifs
|
||||
------------------
|
||||
|
||||
**View Dashboards**
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**View/Edit a Slice**
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
**Query and Visualize with SQL Lab**
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
3
dev-reqs-for-docs.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
sphinx
|
||||
sphinx-rtd-theme
|
||||
sphinxcontrib.youtube
|
||||
@@ -1,11 +1,13 @@
|
||||
codeclimate-test-reporter
|
||||
coveralls
|
||||
flake8
|
||||
flask_cors
|
||||
mock
|
||||
mysqlclient
|
||||
nose
|
||||
psycopg2
|
||||
pylint
|
||||
pythrifthiveapi
|
||||
pyyaml
|
||||
sphinx
|
||||
sphinx-rtd-theme
|
||||
sphinxcontrib.youtube
|
||||
# Also install everything we need to build Sphinx docs
|
||||
-r dev-reqs-for-docs.txt
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
.. image:: _static/img/s.png
|
||||
|
||||
Superset's documentation
|
||||
''''''''''''''''''''''''
|
||||
|
||||
Superset is a data exploration platform designed to be visual, intuitive
|
||||
and interactive.
|
||||
|
||||
|
||||
----------------
|
||||
|
||||
.. warning:: This project was originally named Panoramix, was renamed to
|
||||
|
||||
@@ -4,8 +4,9 @@ Installation & Configuration
|
||||
Getting Started
|
||||
---------------
|
||||
|
||||
Superset is tested using Python 2.7 and Python 3.4+. Python 3 is the recommended version,
|
||||
Python 2.6 won't be supported.
|
||||
Superset is tested against Python ``2.7`` and Python ``3.4``.
|
||||
Airbnb currently uses 2.7.* in production. We do not plan on supporting
|
||||
Python ``2.6``.
|
||||
|
||||
|
||||
OS dependencies
|
||||
@@ -30,7 +31,7 @@ For **Fedora** and **RHEL-derivatives**, the following command will ensure
|
||||
that the required dependencies are installed: ::
|
||||
|
||||
sudo yum upgrade python-setuptools
|
||||
sudo yum install gcc libffi-devel python-devel python-pip python-wheel openssl-devel libsasl2-devel openldap-devel
|
||||
sudo yum install gcc gcc-c++ libffi-devel python-devel python-pip python-wheel openssl-devel libsasl2-devel openldap-devel
|
||||
|
||||
**OSX**, system python is not recommended. brew's python also ships with pip ::
|
||||
|
||||
@@ -195,7 +196,7 @@ Here's a list of some of the recommended packages.
|
||||
+---------------+-------------------------------------+-------------------------------------------------+
|
||||
| sqlite | | ``sqlite://`` |
|
||||
+---------------+-------------------------------------+-------------------------------------------------+
|
||||
| Redshift | ``pip install sqlalchemy-redshift`` | ``redshift+psycopg2://`` |
|
||||
| Redshift | ``pip install sqlalchemy-redshift`` | ``postgresql+psycopg2://`` |
|
||||
+---------------+-------------------------------------+-------------------------------------------------+
|
||||
| MSSQL | ``pip install pymssql`` | ``mssql://`` |
|
||||
+---------------+-------------------------------------+-------------------------------------------------+
|
||||
@@ -205,12 +206,29 @@ Here's a list of some of the recommended packages.
|
||||
+---------------+-------------------------------------+-------------------------------------------------+
|
||||
| Greenplum | ``pip install psycopg2`` | ``postgresql+psycopg2://`` |
|
||||
+---------------+-------------------------------------+-------------------------------------------------+
|
||||
| Athena | ``pip install "PyAthenaJDBC>1.0.9"``| ``awsathena+jdbc://`` |
|
||||
+---------------+-------------------------------------+-------------------------------------------------+
|
||||
|
||||
Note that many other database are supported, the main criteria being the
|
||||
existence of a functional SqlAlchemy dialect and Python driver. Googling
|
||||
the keyword ``sqlalchemy`` in addition of a keyword that describes the
|
||||
database you want to connect to should get you to the right place.
|
||||
|
||||
(AWS) Athena
|
||||
------------
|
||||
|
||||
This currently relies on an unreleased future version of `PyAthenaJDBC <https://github.com/laughingman7743/PyAthenaJDBC>`_. If you're adventurous or simply impatient, you can install directly from git: ::
|
||||
|
||||
pip install git+https://github.com/laughingman7743/PyAthenaJDBC@support_sqlalchemy
|
||||
|
||||
The connection string for Athena looks like this ::
|
||||
|
||||
awsathena+jdbc://{aws_access_key_id}:{aws_secret_access_key}@athena.{region_name}.amazonaws.com/{schema_name}?s3_staging_dir={s3_staging_dir}&...
|
||||
|
||||
Where you need to escape/encode at least the s3_staging_dir, i.e., ::
|
||||
|
||||
s3://... -> s3%3A//...
|
||||
|
||||
|
||||
Caching
|
||||
-------
|
||||
@@ -222,9 +240,11 @@ 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
|
||||
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>`.
|
||||
the `redis <https://pypi.python.org/pypi/redis>`_ Python package: ::
|
||||
|
||||
pip install redis
|
||||
|
||||
For setting your timeouts, this is done in the Superset metadata and goes
|
||||
up the "timeout searchpath", from your slice configuration, to your
|
||||
@@ -373,6 +393,31 @@ your environment.::
|
||||
# assuming $SUPERSET_HOME as the root of the repo
|
||||
cd $SUPERSET_HOME/superset/assets
|
||||
npm install
|
||||
npm run prod
|
||||
npm run build
|
||||
cd $SUPERSET_HOME
|
||||
python setup.py install
|
||||
|
||||
|
||||
Blueprints
|
||||
----------
|
||||
|
||||
`Blueprints are Flask's reusable apps <http://flask.pocoo.org/docs/0.12/blueprints/>`_.
|
||||
Superset allows you to specify an array of Blueprints
|
||||
an array of Blueprints in your ``superset_config`` module. Here's
|
||||
an example on how this can work with a simple Blueprint. By doing
|
||||
so, you can expect Superset to serve a page that says "OK"
|
||||
at the ``/simple_page`` url. This can allow you to run other things such
|
||||
as custom data visualization applications alongside Superset, on the
|
||||
same server.
|
||||
|
||||
..code ::
|
||||
|
||||
from flask import Blueprint
|
||||
simple_page = Blueprint('simple_page', __name__,
|
||||
template_folder='templates')
|
||||
@simple_page.route('/', defaults={'page': 'index'})
|
||||
@simple_page.route('/<page>')
|
||||
def show(page):
|
||||
return "Ok"
|
||||
|
||||
BLUEPRINTS = [simple_page]
|
||||
|
||||
@@ -50,6 +50,17 @@ 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.
|
||||
|
||||
Public
|
||||
""""""
|
||||
It's possible to allow logged out users to access some Superset features.
|
||||
|
||||
By setting ``PUBLIC_ROLE_LIKE_GAMMA = True`` in your ``superset_config.py``,
|
||||
you grant public role the same set of permissions as for the GAMMA role.
|
||||
This is useful if one wants to enable anonymous users to view
|
||||
dashboards. Explicit grant on specific datasets is still required, meaning
|
||||
that you need to edit the ``Public`` role and add the Public data sources
|
||||
to the role manually.
|
||||
|
||||
|
||||
Managing Gamma per data source access
|
||||
-------------------------------------
|
||||
|
||||
@@ -58,3 +58,5 @@ Superset's Jinja context:
|
||||
|
||||
.. autoclass:: superset.jinja_context.PrestoTemplateProcessor
|
||||
:members:
|
||||
|
||||
.. autofunction:: superset.jinja_context.url_param
|
||||
|
||||
@@ -1,100 +1,308 @@
|
||||
Tutorial
|
||||
========
|
||||
Tutorial for Superset Administrators
|
||||
====================================
|
||||
|
||||
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
|
||||
Superset where to find the database you want to
|
||||
query. First go to the database menu
|
||||
This tutorial targets a Superset administrator: someone configuring Superset
|
||||
for an organization on behalf of users. We'll show you how to connect Superset
|
||||
to a new database and configure a table in that database for analysis. You'll
|
||||
also explore the data you've exposed and add a visualization to a dashboard
|
||||
so that you get a feel for the end-to-end user experience.
|
||||
|
||||
.. image:: _static/img/tutorial/db_menu.png
|
||||
:scale: 30 %
|
||||
Connecting to a new database
|
||||
----------------------------
|
||||
|
||||
Now click on the ``+`` button to add a new entry
|
||||
We assume you already have a database configured and can connect to it from the
|
||||
instance on which you’re running Superset. If you’re just testing Superset and
|
||||
want to explore sample data, you can load some
|
||||
`sample PostgreSQL datasets <https://wiki.postgresql.org/wiki/Sample_Databases>`_
|
||||
into a fresh DB, or configure the
|
||||
`example weather data <https://github.com/dylburger/noaa-ghcn-weather-data>`_
|
||||
we use here.
|
||||
|
||||
.. image:: _static/img/tutorial/db_plus.png
|
||||
:scale: 30 %
|
||||
Under the **Sources** menu, select the *Databases* option:
|
||||
|
||||
Fill in an arbitrary reference name for the database, and you SQLAlchemy
|
||||
URI. To figure out how to construct your URI, check out the
|
||||
`SQLAlchemy documentation <http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html>`_.
|
||||
Then you can test your connection. If it works, you'll see a positive popup
|
||||
and list of the tables that SQLAlchemy has found for that URI.
|
||||
.. image:: _static/img/tutorial/tutorial_01_sources_database.png
|
||||
:scale: 70%
|
||||
|
||||
.. image:: _static/img/tutorial/db_added.png
|
||||
:scale: 30 %
|
||||
On the resulting page, click on the green plus sign, near the top left:
|
||||
|
||||
Once your database has been added, it's time to add your table. Navigate
|
||||
using the navigation bar at the top to ``Sources -> Tables`` and click the
|
||||
plus (``+``) sign there (similar to the one ).
|
||||
.. image:: _static/img/tutorial/tutorial_02_add_database.png
|
||||
:scale: 70%
|
||||
|
||||
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, 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.
|
||||
You can configure a number of advanced options on this page, but for
|
||||
this walkthrough, you’ll only need to do **two things**:
|
||||
|
||||
.. image:: _static/img/tutorial/pen.png
|
||||
:scale: 30 %
|
||||
1. Name your database connection:
|
||||
|
||||
Now you're in the table editor, click on the "List Table Column" tab,
|
||||
showing you the list of columns in your table as well as their data types.
|
||||
.. image:: _static/img/tutorial/tutorial_03_database_name.png
|
||||
:scale: 70%
|
||||
|
||||
.. image:: _static/img/tutorial/matrix.png
|
||||
:scale: 30 %
|
||||
2. Provide the SQLAlchemy Connection URI and test the connection:
|
||||
|
||||
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 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``.
|
||||
.. image:: _static/img/tutorial/tutorial_04_sqlalchemy_connection_string.png
|
||||
:scale: 70%
|
||||
|
||||
You should now be back in the ``Table List`` view. Click on the name of the
|
||||
table you just created. You enter the "Explore" view for your table.
|
||||
This example shows the connection string for our test weather database.
|
||||
As noted in the text below the URI, you should refer to the SQLAlchemy
|
||||
documentation on
|
||||
`creating new connection URIs <http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html#database-urls>`_
|
||||
for your target database.
|
||||
|
||||
.. image:: _static/img/tutorial/explore.png
|
||||
:scale: 30 %
|
||||
Click the **Test Connection** button to confirm things work end to end.
|
||||
Once Superset can successfully connect and authenticate, you should see
|
||||
a popup like this:
|
||||
|
||||
The next step is to create a Slice. First, make sure to use a time filter
|
||||
that is relevant.
|
||||
.. image:: _static/img/tutorial/tutorial_05_connection_popup.png
|
||||
:scale: 50%
|
||||
|
||||
.. note::
|
||||
Moreover, you should also see the list of tables Superset can read from
|
||||
the schema you’re connected to, at the bottom of the page:
|
||||
|
||||
You can use some "natural language time expressions"
|
||||
either as relative (as in ``now``, ``4 weeks ago``, or ``1 year ago``) as well
|
||||
as hard date or time expressions (as in ``3015``, ``3016-01-01`` or
|
||||
``May``).
|
||||
.. image:: _static/img/tutorial/tutorial_06_list_of_tables.png
|
||||
:scale: 70%
|
||||
|
||||
Alter the form's option and click ``Query`` until you get to an interesting
|
||||
cut of data, and click ``SAVE AS``, enter a name, and you just created your first
|
||||
slice.
|
||||
If the connection looks good, save the configuration by clicking the **Save**
|
||||
button at the bottom of the page:
|
||||
|
||||
.. image:: _static/img/tutorial/created.png
|
||||
:scale: 30 %
|
||||
.. image:: _static/img/tutorial/tutorial_07_save_button.png
|
||||
:scale: 70%
|
||||
|
||||
This slice is now accessible in the slice list from the
|
||||
``Menu -> Slices`` at any time. Note that this view is easily filterable and
|
||||
searchable.
|
||||
Adding a new table
|
||||
------------------
|
||||
|
||||
.. image:: _static/img/tutorial/search.png
|
||||
:scale: 30 %
|
||||
Now that you’ve configured a database, you’ll need to add specific tables
|
||||
to Superset that you’d like to query.
|
||||
|
||||
Now let's create a dashboard. A dashboard is simply a collection of slices
|
||||
with metadata around their sizes, positions, CSS style and a few other things.
|
||||
Navigate to the dashboard list view ``Menu -> Dashboard`` and click the plus
|
||||
(``+``) sign. In the form, enter a name and pick the slice you just created.
|
||||
Under the **Sources** menu, select the *Tables* option:
|
||||
|
||||
.. image:: _static/img/tutorial/new_dash.png
|
||||
:scale: 30 %
|
||||
.. image:: _static/img/tutorial/tutorial_08_sources_tables.png
|
||||
:scale: 70%
|
||||
|
||||
Hit ``Save``, you should be back in ``Menu -> Dashboard``. Now enter your
|
||||
new dashboard.
|
||||
On the resulting page, click on the green plus sign, near the top left:
|
||||
|
||||
.. image:: _static/img/tutorial/in_new_dash.png
|
||||
:scale: 30 %
|
||||
.. image:: _static/img/tutorial/tutorial_09_add_new_table.png
|
||||
:scale: 70%
|
||||
|
||||
Here you are. You can now resize and move the different slice(s), style them
|
||||
in the CSS modal window, and save right from here. For now, renaming the
|
||||
dashboard or adding on a new slice is done through the dashboard edit view,
|
||||
which is the same form as you used when you originally created the dashboard,
|
||||
and is accessible by clicking the ``edit`` pen icon from the dashboard list
|
||||
view (``Menu -> Dashboards``)
|
||||
You only need a few pieces of information to add a new table to Superset:
|
||||
|
||||
* The name of the table
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_10_table_name.png
|
||||
:scale: 70%
|
||||
|
||||
* The target database from the **Database** drop-down menu (i.e. the one
|
||||
you just added above)
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_11_choose_db.png
|
||||
:scale: 70%
|
||||
|
||||
* Optionally, the database schema. If the table exists in the “default” schema
|
||||
(e.g. the *public* schema in PostgreSQL or Redshift), you can leave the schema
|
||||
field blank.
|
||||
|
||||
Click on the **Save** button to save the configuration:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_07_save_button.png
|
||||
:scale: 70%
|
||||
|
||||
When redirected back to the list of tables, you should see a message indicating
|
||||
that your table was created:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_12_table_creation_success_msg.png
|
||||
:scale: 70%
|
||||
|
||||
This message also directs you to edit the table configuration. We’ll edit a limited
|
||||
portion of the configuration now - just to get you started - and leave the rest for
|
||||
a more advanced tutorial.
|
||||
|
||||
Click on the edit button next to the table you’ve created:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_13_edit_table_config.png
|
||||
:scale: 70%
|
||||
|
||||
On the resulting page, click on the **List Table Column** tab. Here, you’ll define the
|
||||
way you can use specific columns of your table when exploring your data. We’ll run
|
||||
through these options to describe their purpose:
|
||||
|
||||
* If you want users to group metrics by a specific field, mark it as **Groupable**.
|
||||
* If you need to filter on a specific field, mark it as **Filterable**.
|
||||
* Is this field something you’d like to get the distinct count of? Check the **Count
|
||||
Distinct** box.
|
||||
* Is this a metric you want to sum, or get basic summary statistics for? The **Sum**,
|
||||
**Min**, and **Max** columns will help.
|
||||
* The **is temporal** field should be checked for any date or time fields. We’ll cover
|
||||
how this manifests itself in analyses in a moment.
|
||||
|
||||
Here’s how we’ve configured fields for the weather data. Even for measures like the
|
||||
weather measurements (precipitation, snowfall, etc.), it’s ideal to group and filter
|
||||
by these values:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_14_field_config.png
|
||||
|
||||
As with the configurations above, click the **Save** button to save these settings.
|
||||
|
||||
Exploring your data
|
||||
-------------------
|
||||
|
||||
To start exploring your data, simply click on the table name you just created in
|
||||
the list of available tables:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_15_click_table_name.png
|
||||
|
||||
By default, you’ll be presented with a Table View:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_16_datasource_chart_type.png
|
||||
|
||||
Let’s walk through a basic query to get the count of all records in our table.
|
||||
First, we’ll need to change the **Since** filter to capture the range of our data.
|
||||
You can use simple phrases to apply these filters, like "3 years ago":
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_17_choose_time_range.png
|
||||
|
||||
The upper limit for time, the **Until** filter, defaults to "now", which may or may
|
||||
not be what you want.
|
||||
|
||||
Look for the Metrics section under the **GROUP BY** header, and start typing "Count"
|
||||
- you’ll see a list of metrics matching what you type:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_18_choose_metric.png
|
||||
|
||||
Select the *COUNT(\*)* metric, then click the green **Query** button near the top
|
||||
of the explore:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_19_click_query.png
|
||||
|
||||
You’ll see your results in the table:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_20_count_star_result.png
|
||||
|
||||
Let’s group this by the *weather_description* field to get the count of records by
|
||||
the type of weather recorded by adding it to the *Group by* section:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_21_group_by.png
|
||||
|
||||
and run the query:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_22_group_by_result.png
|
||||
|
||||
Let’s find a more useful data point: the top 10 times and places that recorded the
|
||||
highest temperature in 2015.
|
||||
|
||||
We replace *weather_description* with *latitude*, *longitude* and *measurement_date* in the
|
||||
*Group by* section:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_23_group_by_more_dimensions.png
|
||||
|
||||
And replace *COUNT(\*)* with *max__measurement_flag*:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_24_max_metric.png
|
||||
|
||||
The *max__measurement_flag* metric was created when we checked the box under **Max** and
|
||||
next to the *measurement_flag* field, indicating that this field was numeric and that
|
||||
we wanted to find its maximum value when grouped by specific fields.
|
||||
|
||||
In our case, *measurement_flag* is the value of the measurement taken, which clearly
|
||||
depends on the type of measurement (the researchers recorded different values for
|
||||
precipitation and temperature). Therefore, we must filter our query only on records
|
||||
where the *weather_description* is equal to "Maximum temperature", which we do in
|
||||
the **Filters** section at the bottom of the explore:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_25_max_temp_filter.png
|
||||
|
||||
Finally, since we only care about the top 10 measurements, we limit our results to
|
||||
10 records using the *Row limit* option under the **Options** header:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_26_row_limit.png
|
||||
|
||||
We click **Query** and get the following results:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_27_top_10_max_temps.png
|
||||
|
||||
In this dataset, the maximum temperature is recorded in tenths of a degree Celsius.
|
||||
The top value of 1370, measured in the middle of Nevada, is equal to 137 C, or roughly
|
||||
278 degrees F. It’s unlikely this value was correctly recorded. We’ve already been able
|
||||
to investigate some outliers with Superset, but this just scratches the surface of what
|
||||
we can do.
|
||||
|
||||
You may want to do a couple more things with this measure:
|
||||
|
||||
* The default formatting shows values like 1.37k, which may be difficult for some
|
||||
users to read. It’s likely you may want to see the full, comma-separated value.
|
||||
You can change the formatting of any measure by editing its config (*Edit Table
|
||||
Config > List Sql Metric > Edit Metric > D3Format*)
|
||||
* Moreover, you may want to see the temperature measurements in plain degrees C,
|
||||
not tenths of a degree. Or you may want to convert the temperature to degrees
|
||||
Fahrenheit. You can change the SQL that gets executed agains the database, baking
|
||||
the logic into the measure itself (*Edit Table Config > List Sql Metric > Edit
|
||||
Metric > SQL Expression*)
|
||||
|
||||
For now, though, let’s create a better visualization of these data and add it to
|
||||
a dashboard.
|
||||
|
||||
We change the Chart Type to "Distribution - Bar Chart":
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_28_bar_chart.png
|
||||
|
||||
Our filter on Maximum temperature measurements was retained, but the query and
|
||||
formatting options are dependent on the chart type, so you’ll have to set the
|
||||
values again:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_29_bar_chart_series_metrics.png
|
||||
|
||||
You should note the extensive formatting options for this chart: the ability to
|
||||
set axis labels, margins, ticks, etc. To make the data presentable to a broad
|
||||
audience, you’ll want to apply many of these to slices that end up in dashboards.
|
||||
For now, though, we run our query and get the following chart:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_30_bar_chart_results.png
|
||||
:scale: 70%
|
||||
|
||||
Creating a slice and dashboard
|
||||
------------------------------
|
||||
|
||||
This view might be interesting to researchers, so let’s save it. In Superset,
|
||||
a saved query is called a **Slice**.
|
||||
|
||||
To create a slice, click the **Save as** button near the top-left of the
|
||||
explore:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_19_click_query.png
|
||||
|
||||
A popup should appear, asking you to name the slice, and optionally add it to a
|
||||
dashboard. Since we haven’t yet created any dashboards, we can create one and
|
||||
immediately add our slice to it. Let’s do it:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_31_save_slice_to_dashboard.png
|
||||
:scale: 70%
|
||||
|
||||
Click Save, which will direct you back to your original query. We see that
|
||||
our slice and dashboard were successfully created:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_32_save_slice_confirmation.png
|
||||
:scale: 70%
|
||||
|
||||
Let’s check out our new dashboard. We click on the **Dashboards** menu:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_33_dashboard.png
|
||||
|
||||
and find the dashboard we just created:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_34_weather_dashboard.png
|
||||
|
||||
Things seemed to have worked - our slice is here!
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_35_slice_on_dashboard.png
|
||||
:scale: 70%
|
||||
|
||||
But it’s a bit smaller than we might like. Luckily, you can adjust the size
|
||||
of slices in a dashboard by clicking, holding and dragging the bottom-right
|
||||
corner to your desired dimensions:
|
||||
|
||||
.. image:: _static/img/tutorial/tutorial_36_adjust_dimensions.gif
|
||||
:scale: 120%
|
||||
|
||||
After adjusting the size, you’ll be asked to click on the icon near the
|
||||
top-right of the dashboard to save the new configuration.
|
||||
|
||||
Congrats! You’ve successfully linked, analyzed, and visualized data in Superset.
|
||||
There are a wealth of other table configuration and visualization options, so
|
||||
please start exploring and creating slices and dashboards of your own.
|
||||
|
||||
0
jitney_events
Normal file
2
pylint-errors.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
pylint superset --errors-only
|
||||
6
pypi_push.sh
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
# first bump up package.json manually, commit and tag
|
||||
rm superset/assets/dist/*
|
||||
cd superset/assets/
|
||||
rm build/*
|
||||
npm run prod
|
||||
npm run build
|
||||
cd ../..
|
||||
python setup.py register
|
||||
python setup.py sdist upload
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ rm -f .coverage
|
||||
export SUPERSET_CONFIG=tests.superset_test_config
|
||||
set -e
|
||||
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
|
||||
|
||||
50
scripts/permissions_cleanup.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from superset import sm
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def cleanup_permissions():
|
||||
# 1. Clean up duplicates.
|
||||
pvms = sm.get_session.query(sm.permissionview_model).all()
|
||||
print('# of permission view menues is: {}'.format(len(pvms)))
|
||||
pvms_dict = defaultdict(list)
|
||||
for pvm in pvms:
|
||||
pvms_dict[(pvm.permission, pvm.view_menu)].append(pvm)
|
||||
duplicates = [v for v in pvms_dict.values() if len(v) > 1]
|
||||
len(duplicates)
|
||||
|
||||
for pvm_list in duplicates:
|
||||
first_prm = pvm_list[0]
|
||||
roles = set(first_prm.role)
|
||||
for pvm in pvm_list[1:]:
|
||||
roles = roles.union(pvm.role)
|
||||
sm.get_session.delete(pvm)
|
||||
first_prm.roles = list(roles)
|
||||
sm.get_session.commit()
|
||||
|
||||
pvms = sm.get_session.query(sm.permissionview_model).all()
|
||||
print('STage 1: # of permission view menues is: {}'.format(len(pvms)))
|
||||
|
||||
# 2. Clean up None permissions or view menues
|
||||
pvms = sm.get_session.query(sm.permissionview_model).all()
|
||||
for pvm in pvms:
|
||||
if not (pvm.view_menu and pvm.permission):
|
||||
sm.get_session.delete(pvm)
|
||||
sm.get_session.commit()
|
||||
|
||||
pvms = sm.get_session.query(sm.permissionview_model).all()
|
||||
print('Stage 2: # of permission view menues is: {}'.format(len(pvms)))
|
||||
|
||||
# 3. Delete empty permission view menues from roles
|
||||
roles = sm.get_session.query(sm.role_model).all()
|
||||
for role in roles:
|
||||
role.permissions = [p for p in role.permissions if p]
|
||||
sm.get_session.commit()
|
||||
|
||||
# 4. Delete empty roles from permission view menues
|
||||
pvms = sm.get_session.query(sm.permissionview_model).all()
|
||||
for pvm in pvms:
|
||||
pvm.role = [r for r in pvm.role if r]
|
||||
sm.get_session.commit()
|
||||
|
||||
|
||||
cleanup_permissions()
|
||||
21
setup.py
@@ -15,7 +15,7 @@ def get_git_sha():
|
||||
s = str(subprocess.check_output(['git', 'rev-parse', 'HEAD']))
|
||||
return s.strip()
|
||||
except:
|
||||
pass
|
||||
return ""
|
||||
|
||||
GIT_SHA = get_git_sha()
|
||||
version_info = {
|
||||
@@ -42,31 +42,32 @@ setup(
|
||||
zip_safe=False,
|
||||
scripts=['superset/bin/superset'],
|
||||
install_requires=[
|
||||
'boto3==1.4.4',
|
||||
'celery==3.1.23',
|
||||
'cryptography==1.5.3',
|
||||
'cryptography==1.7.2',
|
||||
'flask-appbuilder==1.8.1',
|
||||
'flask-cache==0.13.1',
|
||||
'flask-migrate==1.5.1',
|
||||
'flask-script==2.0.5',
|
||||
'flask-testing==0.5.0',
|
||||
'flask-sqlalchemy==2.0',
|
||||
'flask-testing==0.6.1',
|
||||
'future>=0.16.0, <0.17',
|
||||
'humanize==0.5.1',
|
||||
'gunicorn==19.6.0',
|
||||
'markdown==2.6.6',
|
||||
'markdown==2.6.8',
|
||||
'pandas==0.18.1',
|
||||
'parsedatetime==2.0.0',
|
||||
'pydruid==0.3.1',
|
||||
'PyHive>=0.2.1',
|
||||
'python-dateutil==2.5.3',
|
||||
'requests==2.10.0',
|
||||
'simplejson==3.8.2',
|
||||
'python-dateutil==2.6.0',
|
||||
'requests==2.13.0',
|
||||
'simplejson==3.10.0',
|
||||
'six==1.10.0',
|
||||
'sqlalchemy==1.0.13',
|
||||
'sqlalchemy-utils==0.32.7',
|
||||
'sqlalchemy==1.1.5',
|
||||
'sqlalchemy-utils==0.32.12',
|
||||
'sqlparse==0.1.19',
|
||||
'thrift>=0.9.3',
|
||||
'thrift-sasl>=0.2.1',
|
||||
'werkzeug==0.11.10',
|
||||
],
|
||||
extras_require={
|
||||
'cors': ['Flask-Cors>=2.0.0'],
|
||||
|
||||
@@ -5,37 +5,59 @@ from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
import os
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
from flask import Flask, redirect
|
||||
from flask_appbuilder import SQLA, AppBuilder, IndexView
|
||||
from flask_appbuilder.baseviews import expose
|
||||
from flask_cache import Cache
|
||||
from flask_migrate import Migrate
|
||||
from superset.source_registry import SourceRegistry
|
||||
from flask_wtf.csrf import CSRFProtect
|
||||
from werkzeug.contrib.fixers import ProxyFix
|
||||
from superset import utils
|
||||
|
||||
from superset.connectors.connector_registry import ConnectorRegistry
|
||||
from superset import utils, config # noqa
|
||||
|
||||
|
||||
APP_DIR = os.path.dirname(__file__)
|
||||
CONFIG_MODULE = os.environ.get('SUPERSET_CONFIG', 'superset.config')
|
||||
|
||||
with open(APP_DIR + '/static/assets/backendSync.json', 'r') as f:
|
||||
frontend_config = json.load(f)
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(CONFIG_MODULE)
|
||||
conf = app.config
|
||||
|
||||
for bp in conf.get('BLUEPRINTS'):
|
||||
try:
|
||||
print("Registering blueprint: '{}'".format(bp.name))
|
||||
app.register_blueprint(bp)
|
||||
except Exception as e:
|
||||
print("blueprint registration failed")
|
||||
logging.exception(e)
|
||||
|
||||
if conf.get('SILENCE_FAB'):
|
||||
logging.getLogger('flask_appbuilder').setLevel(logging.ERROR)
|
||||
|
||||
if not app.debug:
|
||||
# In production mode, add log handler to sys.stderr.
|
||||
app.logger.addHandler(logging.StreamHandler())
|
||||
app.logger.setLevel(logging.INFO)
|
||||
logging.getLogger('pyhive.presto').setLevel(logging.INFO)
|
||||
|
||||
db = SQLA(app)
|
||||
|
||||
if conf.get('WTF_CSRF_ENABLED'):
|
||||
csrf = CSRFProtect(app)
|
||||
|
||||
utils.pessimistic_connection_handling(db.engine.pool)
|
||||
|
||||
cache = Cache(app, config=app.config.get('CACHE_CONFIG'))
|
||||
cache = utils.setup_cache(app, conf.get('CACHE_CONFIG'))
|
||||
tables_cache = utils.setup_cache(app, conf.get('TABLE_NAMES_CACHE_CONFIG'))
|
||||
|
||||
migrate = Migrate(app, db, directory=APP_DIR + "/migrations")
|
||||
|
||||
@@ -87,6 +109,6 @@ results_backend = app.config.get("RESULTS_BACKEND")
|
||||
# Registering sources
|
||||
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)
|
||||
ConnectorRegistry.register_sources(module_datasource_map)
|
||||
|
||||
from superset import views, config # noqa
|
||||
from superset import views # noqa
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"document": true,
|
||||
},
|
||||
"rules": {
|
||||
"prefer-template": 0,
|
||||
"new-cap": 0,
|
||||
|
||||
2278
superset/assets/backendSync.json
Normal file
45
superset/assets/branding/Full Lockup With Text.svg
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="210px" height="202px" viewBox="0 0 210 202" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Full Lockup With Text</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="path-1"></path>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-5" y="-5" width="122.183871" height="65.65">
|
||||
<rect x="-5" y="-5" width="122.183871" height="65.65" fill="white"></rect>
|
||||
<use xlink:href="#path-1" fill="black"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="Main" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Superset" transform="translate(-177.000000, -812.000000)">
|
||||
<g id="Full-Lockup-With-Text" transform="translate(177.000000, 812.000000)">
|
||||
<g id="Group-7" transform="translate(0.500000, 0.500000)">
|
||||
<g id="Group-17">
|
||||
<g id="Group-6-Copy">
|
||||
<g id="Group" fill="#484848">
|
||||
<path d="M0,80.85 C8.56021505,80.85 15.0179211,84.6 15.0179211,94.8 L15.0179211,116.1 C15.0179211,135.9 25.9810036,145.2 44.1526882,145.2 L48.8082437,145.2 L48.8082437,130.05 L44.3028674,130.05 C36.944086,130.05 31.8379928,126.6 31.8379928,116.55 L31.8379928,91.5 C31.8379928,81.9 26.281362,75 16.6698925,72.6 C26.281362,70.05 31.8379928,63.3 31.8379928,53.7 L31.8379928,28.5 C31.8379928,18.45 36.944086,15.15 44.3028674,15.15 L48.8082437,15.15 L48.8082437,0 L44.1526882,0 C25.9810036,0 15.0179211,9.15 15.0179211,28.95 L15.0179211,50.25 C15.0179211,60.45 8.56021505,64.2 0,64.2 L0,80.85 Z" id="{-copy-4"></path>
|
||||
<path d="M160.691756,80.85 C169.251971,80.85 175.709677,84.6 175.709677,94.8 L175.709677,116.1 C175.709677,135.9 186.67276,145.2 204.844444,145.2 L209.5,145.2 L209.5,130.05 L204.994624,130.05 C197.635842,130.05 192.529749,126.6 192.529749,116.55 L192.529749,91.5 C192.529749,81.9 186.973118,75 177.361649,72.6 C186.973118,70.05 192.529749,63.3 192.529749,53.7 L192.529749,28.5 C192.529749,18.45 197.635842,15.15 204.994624,15.15 L209.5,15.15 L209.5,0 L204.844444,0 C186.67276,0 175.709677,9.15 175.709677,28.95 L175.709677,50.25 C175.709677,60.45 169.251971,64.2 160.691756,64.2 L160.691756,80.85 Z" id="{-copy-5" transform="translate(185.095878, 72.600000) rotate(-180.000000) translate(-185.095878, -72.600000) "></path>
|
||||
<path d="M104.67491,86.25 C95.8143369,95.85 87.8548387,100.65 77.6426523,100.65 C60.9727599,100.65 48.8082437,88.95 48.8082437,72.9 C48.8082437,56.85 60.9727599,45 77.6426523,45 C87.7046595,45 96.7154122,50.25 105.125448,59.85 C113.685663,50.4 122.546237,45 132.157706,45 C148.827599,45 160.992115,56.85 160.992115,72.9 C160.992115,88.95 148.827599,100.65 132.157706,100.65 C121.94552,100.65 113.235125,95.85 104.67491,86.25 Z M77.9430108,62.1 C70.8845878,62.1 66.6795699,66.9 66.6795699,73.05 C66.6795699,79.2 70.8845878,83.85 77.9430108,83.85 C83.8,83.85 89.0562724,79.35 94.0121864,73.35 C88.755914,66.9 83.9501792,62.1 77.9430108,62.1 Z M131.857348,83.85 C126.000358,83.85 121.044444,79.2 115.788172,73.05 C121.194624,66.6 125.850179,62.1 131.857348,62.1 C138.915771,62.1 143.120789,66.9 143.120789,73.05 C143.120789,79.2 138.915771,83.85 131.857348,83.85 Z" id="∞"></path>
|
||||
</g>
|
||||
<rect id="Bottom" fill="#FFFFFF" transform="translate(116.947287, 85.695730) rotate(-320.000000) translate(-116.947287, -85.695730) " x="107.936535" y="73.3847709" width="18.0215054" height="24.6219184"></rect>
|
||||
<rect id="Top" fill="#FFFFFF" transform="translate(91.942412, 61.695730) rotate(-320.000000) translate(-91.942412, -61.695730) " x="82.9316592" y="49.3847709" width="18.0215054" height="24.6219184"></rect>
|
||||
</g>
|
||||
<text id="Superset-Copy" font-family="Roboto-Black, Roboto" font-size="37.5" font-weight="700" letter-spacing="0.500625014" fill="#484848">
|
||||
<tspan x="26.281362" y="192.625">Superset</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-10" transform="translate(49.500000, 45.500000)">
|
||||
<g id="WORK-SPACE">
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="∞-copy-2" fill="#484848"></path>
|
||||
<path d="M35.3031737,7.82736301 L54.6231734,7.82736301 C54.6231734,7.82736301 54.1382597,11.9130391 54.1201021,16.2068622 C54.1019446,20.5006853 53.079701,24.1223631 53.079701,24.1223631 L35.3031737,24.1223631 L35.3031737,7.82736301 Z" id="Path" fill="#00D1C1" transform="translate(44.963174, 15.974863) rotate(-50.000000) translate(-44.963174, -15.974863) "></path>
|
||||
<rect id="Path-Copy" fill="#00D1C1" transform="translate(67.518574, 40.130521) rotate(-50.000000) translate(-67.518574, -40.130521) " x="57.8585742" y="31.9830205" width="19.3199997" height="16.2950001"></rect>
|
||||
<path d="M29.134767,17.1 C35.1419355,17.1 39.9476703,21.9 45.2039427,28.35 C40.2480287,34.35 34.9917563,38.85 29.134767,38.85 C22.0763441,38.85 17.8713262,34.2 17.8713262,28.05 C17.8713262,21.9 22.0763441,17.1 29.134767,17.1 Z" id="Path" fill="#FFFFFF"></path>
|
||||
<path d="M83.0491039,38.85 C77.1921147,38.85 72.2362007,34.2 66.9799283,28.05 C72.3863799,21.6 77.0419355,17.1 83.0491039,17.1 C90.1075269,17.1 94.3125448,21.9 94.3125448,28.05 C94.3125448,34.2 90.1075269,38.85 83.0491039,38.85 Z" id="Path" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
<use id="∞-copy-2" stroke="#FFFFFF" mask="url(#mask-2)" stroke-width="10" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.6 KiB |
BIN
superset/assets/branding/Full Lockup With Text@2x.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
34
superset/assets/branding/Full Lockup Without Text@1x.svg
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="210px" height="146px" viewBox="0 0 210 146" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Full Lockup Without Text@1x</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="path-1"></path>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-5" y="-5" width="122.183871" height="65.65">
|
||||
<rect x="-5" y="-5" width="122.183871" height="65.65" fill="white"></rect>
|
||||
<use xlink:href="#path-1" fill="black"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="Main" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Superset" transform="translate(-177.000000, -466.000000)">
|
||||
<g id="Full-Lockup-Without-Text" transform="translate(177.000000, 466.000000)">
|
||||
<path d="M0.5,81.35 C9.06021505,81.35 15.5179211,85.1 15.5179211,95.3 L15.5179211,116.6 C15.5179211,136.4 26.4810036,145.7 44.6526882,145.7 L49.3082437,145.7 L49.3082437,130.55 L44.8028674,130.55 C37.444086,130.55 32.3379928,127.1 32.3379928,117.05 L32.3379928,92 C32.3379928,82.4 26.781362,75.5 17.1698925,73.1 C26.781362,70.55 32.3379928,63.8 32.3379928,54.2 L32.3379928,29 C32.3379928,18.95 37.444086,15.65 44.8028674,15.65 L49.3082437,15.65 L49.3082437,0.5 L44.6526882,0.5 C26.4810036,0.5 15.5179211,9.65 15.5179211,29.45 L15.5179211,50.75 C15.5179211,60.95 9.06021505,64.7 0.5,64.7 L0.5,81.35 Z" id="{-copy-4" fill="#484848"></path>
|
||||
<path d="M161.191756,81.35 C169.751971,81.35 176.209677,85.1 176.209677,95.3 L176.209677,116.6 C176.209677,136.4 187.17276,145.7 205.344444,145.7 L210,145.7 L210,130.55 L205.494624,130.55 C198.135842,130.55 193.029749,127.1 193.029749,117.05 L193.029749,92 C193.029749,82.4 187.473118,75.5 177.861649,73.1 C187.473118,70.55 193.029749,63.8 193.029749,54.2 L193.029749,29 C193.029749,18.95 198.135842,15.65 205.494624,15.65 L210,15.65 L210,0.5 L205.344444,0.5 C187.17276,0.5 176.209677,9.65 176.209677,29.45 L176.209677,50.75 C176.209677,60.95 169.751971,64.7 161.191756,64.7 L161.191756,81.35 Z" id="{-copy-5" fill="#484848" transform="translate(185.595878, 73.100000) rotate(-180.000000) translate(-185.595878, -73.100000) "></path>
|
||||
<path d="M105.366667,86.75 C96.5060932,96.35 88.546595,101.15 78.3344086,101.15 C61.6645161,101.15 49.5,89.45 49.5,73.4 C49.5,57.35 61.6645161,45.5 78.3344086,45.5 C88.3964158,45.5 97.4071685,50.75 105.817204,60.35 C114.377419,50.9 123.237993,45.5 132.849462,45.5 C149.519355,45.5 161.683871,57.35 161.683871,73.4 C161.683871,89.45 149.519355,101.15 132.849462,101.15 C122.637276,101.15 113.926882,96.35 105.366667,86.75 Z M78.634767,62.6 C71.5763441,62.6 67.3713262,67.4 67.3713262,73.55 C67.3713262,79.7 71.5763441,84.35 78.634767,84.35 C84.4917563,84.35 89.7480287,79.85 94.7039427,73.85 C89.4476703,67.4 84.6419355,62.6 78.634767,62.6 Z M132.549104,84.35 C126.692115,84.35 121.736201,79.7 116.479928,73.55 C121.88638,67.1 126.541935,62.6 132.549104,62.6 C139.607527,62.6 143.812545,67.4 143.812545,73.55 C143.812545,79.7 139.607527,84.35 132.549104,84.35 Z" id="∞" fill="#484848"></path>
|
||||
<rect id="Bottom" fill="#FFFFFF" transform="translate(117.815969, 86.222742) rotate(-320.000000) translate(-117.815969, -86.222742) " x="108.805216" y="73.9117829" width="18.0215054" height="24.6219184"></rect>
|
||||
<polygon id="Top" fill="#FFFFFF" transform="translate(93.488745, 61.141018) rotate(-320.000000) translate(-93.488745, -61.141018) " points="84.477992 50.894853 102.499497 50.894853 102.499497 71.3871824 84.5471936 70.9586997"></polygon>
|
||||
<g id="Group-10" transform="translate(49.500000, 45.500000)">
|
||||
<g id="WORK-SPACE">
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="∞-copy-2" fill="#484848"></path>
|
||||
<path d="M35.3031737,7.82736301 L54.6231734,7.82736301 C54.6231734,7.82736301 54.1382597,11.9130391 54.1201021,16.2068622 C54.1019446,20.5006853 53.079701,24.1223631 53.079701,24.1223631 L35.3031737,24.1223631 L35.3031737,7.82736301 Z" id="Path" fill="#00D1C1" transform="translate(44.963174, 15.974863) rotate(-50.000000) translate(-44.963174, -15.974863) "></path>
|
||||
<rect id="Path-Copy" fill="#00D1C1" transform="translate(67.518574, 40.130521) rotate(-50.000000) translate(-67.518574, -40.130521) " x="57.8585742" y="31.9830205" width="19.3199997" height="16.2950001"></rect>
|
||||
<path d="M29.134767,17.1 C35.1419355,17.1 39.9476703,21.9 45.2039427,28.35 C40.2480287,34.35 34.9917563,38.85 29.134767,38.85 C22.0763441,38.85 17.8713262,34.2 17.8713262,28.05 C17.8713262,21.9 22.0763441,17.1 29.134767,17.1 Z" id="Path" fill="#FFFFFF"></path>
|
||||
<path d="M83.0491039,38.85 C77.1921147,38.85 72.2362007,34.2 66.9799283,28.05 C72.3863799,21.6 77.0419355,17.1 83.0491039,17.1 C90.1075269,17.1 94.3125448,21.9 94.3125448,28.05 C94.3125448,34.2 90.1075269,38.85 83.0491039,38.85 Z" id="Path" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
<use id="∞-copy-2" stroke="#FFFFFF" mask="url(#mask-2)" stroke-width="10" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.1 KiB |
BIN
superset/assets/branding/Full Lockup Without Text@2x.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
35
superset/assets/branding/Horizontal.svg
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="350px" height="66px" viewBox="0 0 350 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Horizontal</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="path-1"></path>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-5" y="-5" width="122.183871" height="65.65">
|
||||
<rect x="-5" y="-5" width="122.183871" height="65.65" fill="white"></rect>
|
||||
<use xlink:href="#path-1" fill="black"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="Main" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Superset" transform="translate(-319.000000, -195.000000)">
|
||||
<g id="Horizontal" transform="translate(324.000000, 200.000000)">
|
||||
<g id="Group-3">
|
||||
<text id="Superset" font-family="Roboto-Black, Roboto" font-size="50" font-weight="700" letter-spacing="0.670000017" fill="#484848">
|
||||
<tspan x="137" y="46">Superse</tspan>
|
||||
<tspan x="328.335508" y="46">t</tspan>
|
||||
</text>
|
||||
<g id="Group-10-Copy-8">
|
||||
<g id="WORK-SPACE">
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="∞-copy-2" fill="#484848"></path>
|
||||
<path d="M35.3031737,7.82736301 L54.6231734,7.82736301 C54.6231734,7.82736301 54.1382597,11.9130391 54.1201021,16.2068622 C54.1019446,20.5006853 53.079701,24.1223631 53.079701,24.1223631 L35.3031737,24.1223631 L35.3031737,7.82736301 Z" id="Path" fill="#00D1C1" transform="translate(44.963174, 15.974863) rotate(-50.000000) translate(-44.963174, -15.974863) "></path>
|
||||
<rect id="Path-Copy" fill="#00D1C1" transform="translate(67.518574, 40.130521) rotate(-50.000000) translate(-67.518574, -40.130521) " x="57.8585742" y="31.9830205" width="19.3199997" height="16.2950001"></rect>
|
||||
<path d="M29.134767,17.1 C35.1419355,17.1 39.9476703,21.9 45.2039427,28.35 C40.2480287,34.35 34.9917563,38.85 29.134767,38.85 C22.0763441,38.85 17.8713262,34.2 17.8713262,28.05 C17.8713262,21.9 22.0763441,17.1 29.134767,17.1 Z" id="Path" fill="#FFFFFF"></path>
|
||||
<path d="M83.0491039,38.85 C77.1921147,38.85 72.2362007,34.2 66.9799283,28.05 C72.3863799,21.6 77.0419355,17.1 83.0491039,17.1 C90.1075269,17.1 94.3125448,21.9 94.3125448,28.05 C94.3125448,34.2 90.1075269,38.85 83.0491039,38.85 Z" id="Path" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
<use id="∞-copy-2" stroke="#FFFFFF" mask="url(#mask-2)" stroke-width="10" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
BIN
superset/assets/branding/Horizontal@2x.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
superset/assets/branding/Solo Mark.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
27
superset/assets/branding/Solo Mark@1x.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="123px" height="66px" viewBox="0 0 123 66" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Solo Mark@1x</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="path-1"></path>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-5" y="-5" width="122.183871" height="65.65">
|
||||
<rect x="-5" y="-5" width="122.183871" height="65.65" fill="white"></rect>
|
||||
<use xlink:href="#path-1" fill="black"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="Main" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Superset" transform="translate(-787.000000, -557.000000)">
|
||||
<g id="Solo-Mark" transform="translate(792.000000, 562.000000)">
|
||||
<g id="WORK-SPACE">
|
||||
<path d="M55.8666667,41.25 C64.4268817,50.85 73.137276,55.65 83.3494624,55.65 C100.019355,55.65 112.183871,43.95 112.183871,27.9 C112.183871,11.85 100.019355,0 83.3494624,0 C73.7379928,0 64.8774194,5.4 56.3172043,14.85 C47.9071685,5.25 38.8964158,0 28.8344086,0 C12.1645161,0 -2.84217094e-14,11.85 -2.84217094e-14,27.9 C-2.84217094e-14,43.95 12.1645161,55.65 28.8344086,55.65 C39.046595,55.65 47.0060932,50.85 55.8666667,41.25 Z" id="∞-copy-2" fill="#484848"></path>
|
||||
<path d="M35.3031737,7.82736301 L54.6231734,7.82736301 C54.6231734,7.82736301 54.1382597,11.9130391 54.1201021,16.2068622 C54.1019446,20.5006853 53.079701,24.1223631 53.079701,24.1223631 L35.3031737,24.1223631 L35.3031737,7.82736301 Z" id="Path" fill="#00D1C1" transform="translate(44.963174, 15.974863) rotate(-50.000000) translate(-44.963174, -15.974863) "></path>
|
||||
<rect id="Path-Copy" fill="#00D1C1" transform="translate(67.518574, 40.130521) rotate(-50.000000) translate(-67.518574, -40.130521) " x="57.8585742" y="31.9830205" width="19.3199997" height="16.2950001"></rect>
|
||||
<path d="M29.134767,17.1 C35.1419355,17.1 39.9476703,21.9 45.2039427,28.35 C40.2480287,34.35 34.9917563,38.85 29.134767,38.85 C22.0763441,38.85 17.8713262,34.2 17.8713262,28.05 C17.8713262,21.9 22.0763441,17.1 29.134767,17.1 Z" id="Path" fill="#FFFFFF"></path>
|
||||
<path d="M83.0491039,38.85 C77.1921147,38.85 72.2362007,34.2 66.9799283,28.05 C72.3863799,21.6 77.0419355,17.1 83.0491039,17.1 C90.1075269,17.1 94.3125448,21.9 94.3125448,28.05 C94.3125448,34.2 90.1075269,38.85 83.0491039,38.85 Z" id="Path" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
<use id="∞-copy-2" stroke="#FFFFFF" mask="url(#mask-2)" stroke-width="10" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
1
superset/assets/docs
Symbolic link
@@ -0,0 +1 @@
|
||||
../../docs/_build/html/
|
||||
BIN
superset/assets/images/s.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 106 KiB |
BIN
superset/assets/images/tutorial/tutorial_01_sources_database.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
superset/assets/images/tutorial/tutorial_02_add_database.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
superset/assets/images/tutorial/tutorial_03_database_name.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 52 KiB |
BIN
superset/assets/images/tutorial/tutorial_05_connection_popup.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
superset/assets/images/tutorial/tutorial_06_list_of_tables.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
superset/assets/images/tutorial/tutorial_07_save_button.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
superset/assets/images/tutorial/tutorial_08_sources_tables.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
superset/assets/images/tutorial/tutorial_09_add_new_table.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
superset/assets/images/tutorial/tutorial_10_table_name.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
superset/assets/images/tutorial/tutorial_11_choose_db.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 32 KiB |
BIN
superset/assets/images/tutorial/tutorial_14_field_config.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
superset/assets/images/tutorial/tutorial_15_click_table_name.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 11 KiB |
BIN
superset/assets/images/tutorial/tutorial_18_choose_metric.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
superset/assets/images/tutorial/tutorial_19_click_query.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
BIN
superset/assets/images/tutorial/tutorial_21_group_by.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
superset/assets/images/tutorial/tutorial_22_group_by_result.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
BIN
superset/assets/images/tutorial/tutorial_24_max_metric.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
superset/assets/images/tutorial/tutorial_25_max_temp_filter.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
superset/assets/images/tutorial/tutorial_26_row_limit.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
superset/assets/images/tutorial/tutorial_27_top_10_max_temps.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
superset/assets/images/tutorial/tutorial_28_bar_chart.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 24 KiB |
BIN
superset/assets/images/tutorial/tutorial_33_dashboard.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 123 KiB |
BIN
superset/assets/images/viz_thumbnails/dual_line.png
Normal file → Executable file
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 162 KiB |
@@ -1,3 +1,4 @@
|
||||
/* global notify */
|
||||
import shortid from 'shortid';
|
||||
import { now } from '../modules/dates';
|
||||
const $ = require('jquery');
|
||||
@@ -24,7 +25,6 @@ export const SET_ACTIVE_SOUTHPANE_TAB = 'SET_ACTIVE_SOUTHPANE_TAB';
|
||||
export const ADD_ALERT = 'ADD_ALERT';
|
||||
export const REMOVE_ALERT = 'REMOVE_ALERT';
|
||||
export const REFRESH_QUERIES = 'REFRESH_QUERIES';
|
||||
export const SET_NETWORK_STATUS = 'SET_NETWORK_STATUS';
|
||||
export const RUN_QUERY = 'RUN_QUERY';
|
||||
export const START_QUERY = 'START_QUERY';
|
||||
export const STOP_QUERY = 'STOP_QUERY';
|
||||
@@ -34,11 +34,25 @@ export const QUERY_FAILED = 'QUERY_FAILED';
|
||||
export const CLEAR_QUERY_RESULTS = 'CLEAR_QUERY_RESULTS';
|
||||
export const REMOVE_DATA_PREVIEW = 'REMOVE_DATA_PREVIEW';
|
||||
export const CHANGE_DATA_PREVIEW_ID = 'CHANGE_DATA_PREVIEW_ID';
|
||||
export const SAVE_QUERY = 'SAVE_QUERY';
|
||||
|
||||
export function resetState() {
|
||||
return { type: RESET_STATE };
|
||||
}
|
||||
|
||||
export function saveQuery(query) {
|
||||
const url = '/savedqueryviewapi/api/create';
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url,
|
||||
data: query,
|
||||
success: () => notify.success('Your query was saved'),
|
||||
error: () => notify.error('Your query could not be saved'),
|
||||
dataType: 'json',
|
||||
});
|
||||
return { type: SAVE_QUERY };
|
||||
}
|
||||
|
||||
export function startQuery(query) {
|
||||
Object.assign(query, {
|
||||
id: query.id ? query.id : shortid.generate(),
|
||||
@@ -99,7 +113,6 @@ export function fetchQueryResults(query) {
|
||||
export function runQuery(query) {
|
||||
return function (dispatch) {
|
||||
dispatch(startQuery(query));
|
||||
const sqlJsonUrl = '/superset/sql_json/';
|
||||
const sqlJsonRequest = {
|
||||
client_id: query.id,
|
||||
database_id: query.dbId,
|
||||
@@ -112,6 +125,7 @@ export function runQuery(query) {
|
||||
tmp_table_name: query.tempTableName,
|
||||
select_as_cta: query.ctas,
|
||||
};
|
||||
const sqlJsonUrl = '/superset/sql_json/' + location.search;
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
@@ -142,6 +156,24 @@ export function runQuery(query) {
|
||||
};
|
||||
}
|
||||
|
||||
export function postStopQuery(query) {
|
||||
return function (dispatch) {
|
||||
const stopQueryUrl = '/superset/stop_query/';
|
||||
const stopQueryRequestData = { client_id: query.id };
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
url: stopQueryUrl,
|
||||
data: stopQueryRequestData,
|
||||
success() {
|
||||
if (!query.runAsync) {
|
||||
dispatch(stopQuery(query));
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function setDatabases(databases) {
|
||||
return { type: SET_DATABASES, databases };
|
||||
}
|
||||
@@ -155,10 +187,6 @@ export function cloneQueryToNewTab(query) {
|
||||
return { type: CLONE_QUERY_TO_NEW_TAB, query };
|
||||
}
|
||||
|
||||
export function setNetworkStatus(networkOn) {
|
||||
return { type: SET_NETWORK_STATUS, networkOn };
|
||||
}
|
||||
|
||||
export function addAlert(alert) {
|
||||
const o = Object.assign({}, alert);
|
||||
o.id = shortid.generate();
|
||||
@@ -213,9 +241,9 @@ export function mergeTable(table, query) {
|
||||
return { type: MERGE_TABLE, table, query };
|
||||
}
|
||||
|
||||
export function addTable(query, tableName) {
|
||||
export function addTable(query, tableName, schemaName) {
|
||||
return function (dispatch) {
|
||||
let url = `/superset/table/${query.dbId}/${tableName}/${query.schema}/`;
|
||||
let url = `/superset/table/${query.dbId}/${tableName}/${schemaName}/`;
|
||||
$.get(url, (data) => {
|
||||
const dataPreviewQuery = {
|
||||
id: shortid.generate(),
|
||||
@@ -232,7 +260,7 @@ export function addTable(query, tableName) {
|
||||
Object.assign(data, {
|
||||
dbId: query.dbId,
|
||||
queryEditorId: query.id,
|
||||
schema: query.schema,
|
||||
schema: schemaName,
|
||||
expanded: true,
|
||||
}), dataPreviewQuery)
|
||||
);
|
||||
@@ -248,12 +276,12 @@ export function addTable(query, tableName) {
|
||||
);
|
||||
});
|
||||
|
||||
url = `/superset/extra_table_metadata/${query.dbId}/${tableName}/${query.schema}/`;
|
||||
url = `/superset/extra_table_metadata/${query.dbId}/${tableName}/${schemaName}/`;
|
||||
$.get(url, (data) => {
|
||||
const table = {
|
||||
dbId: query.dbId,
|
||||
queryEditorId: query.id,
|
||||
schema: query.schema,
|
||||
schema: schemaName,
|
||||
name: tableName,
|
||||
};
|
||||
Object.assign(table, data);
|
||||
@@ -298,3 +326,44 @@ export function removeTable(table) {
|
||||
export function refreshQueries(alteredQueries) {
|
||||
return { type: REFRESH_QUERIES, alteredQueries };
|
||||
}
|
||||
|
||||
export function popStoredQuery(urlId) {
|
||||
return function (dispatch) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: `/kv/${urlId}`,
|
||||
success: (data) => {
|
||||
const newQuery = JSON.parse(data);
|
||||
const queryEditorProps = {
|
||||
title: newQuery.title ? newQuery.title : 'shared query',
|
||||
dbId: newQuery.dbId ? parseInt(newQuery.dbId, 10) : null,
|
||||
schema: newQuery.schema ? newQuery.schema : null,
|
||||
autorun: newQuery.autorun ? newQuery.autorun : false,
|
||||
sql: newQuery.sql ? newQuery.sql : 'SELECT ...',
|
||||
};
|
||||
dispatch(addQueryEditor(queryEditorProps));
|
||||
},
|
||||
error: () => notify.error("The query couldn't be loaded"),
|
||||
});
|
||||
};
|
||||
}
|
||||
export function popSavedQuery(saveQueryId) {
|
||||
return function (dispatch) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: `/savedqueryviewapi/api/get/${saveQueryId}`,
|
||||
success: (data) => {
|
||||
const sq = data.result;
|
||||
const queryEditorProps = {
|
||||
title: sq.label,
|
||||
dbId: sq.db_id ? parseInt(sq.db_id, 10) : null,
|
||||
schema: sq.schema,
|
||||
autorun: false,
|
||||
sql: sq.sql,
|
||||
};
|
||||
dispatch(addQueryEditor(queryEditorProps));
|
||||
},
|
||||
error: () => notify.error("The query couldn't be loaded"),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,22 @@ import { areArraysShallowEqual } from '../../reduxUtils';
|
||||
|
||||
const langTools = ace.acequire('ace/ext/language_tools');
|
||||
|
||||
const keywords = (
|
||||
'SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|AND|OR|GROUP|BY|ORDER|LIMIT|OFFSET|HAVING|AS|CASE|' +
|
||||
'WHEN|ELSE|END|TYPE|LEFT|RIGHT|JOIN|ON|OUTER|DESC|ASC|UNION|CREATE|TABLE|PRIMARY|KEY|IF|' +
|
||||
'FOREIGN|NOT|REFERENCES|DEFAULT|NULL|INNER|CROSS|NATURAL|DATABASE|DROP|GRANT'
|
||||
);
|
||||
|
||||
const dataTypes = (
|
||||
'INT|NUMERIC|DECIMAL|DATE|VARCHAR|CHAR|BIGINT|FLOAT|DOUBLE|BIT|BINARY|TEXT|SET|TIMESTAMP|' +
|
||||
'MONEY|REAL|NUMBER|INTEGER'
|
||||
);
|
||||
|
||||
const sqlKeywords = [].concat(keywords.split('|'), dataTypes.split('|'));
|
||||
const sqlWords = sqlKeywords.map(s => ({
|
||||
name: s, value: s, score: 60, meta: 'sql',
|
||||
}));
|
||||
|
||||
const propTypes = {
|
||||
actions: React.PropTypes.object.isRequired,
|
||||
onBlur: React.PropTypes.func,
|
||||
@@ -80,14 +96,14 @@ class AceEditorWrapper extends React.PureComponent {
|
||||
});
|
||||
words = words.concat(Object.keys(columns).map(col => (
|
||||
{ name: col, value: col, score: 50, meta: 'column' }
|
||||
)));
|
||||
)), sqlWords);
|
||||
|
||||
this.setState({ words }, () => {
|
||||
const completer = {
|
||||
getCompletions: this.getCompletions.bind(this),
|
||||
};
|
||||
if (langTools) {
|
||||
langTools.setCompleters([completer, langTools.keyWordCompleter]);
|
||||
langTools.setCompleters([completer]);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -98,10 +114,9 @@ class AceEditorWrapper extends React.PureComponent {
|
||||
theme="github"
|
||||
onLoad={this.onEditorLoad.bind(this)}
|
||||
onBlur={this.onBlur.bind(this)}
|
||||
minLines={8}
|
||||
maxLines={30}
|
||||
minLines={12}
|
||||
maxLines={12}
|
||||
onChange={this.textChange.bind(this)}
|
||||
height="200px"
|
||||
width="100%"
|
||||
editorProps={{ $blockScrolling: true }}
|
||||
enableLiveAutocompletion
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Alert } from 'react-bootstrap';
|
||||
|
||||
class Alerts extends React.PureComponent {
|
||||
removeAlert(alert) {
|
||||
this.props.actions.removeAlert(alert);
|
||||
}
|
||||
render() {
|
||||
const alerts = this.props.alerts.map((alert) =>
|
||||
<Alert
|
||||
key={alert.id}
|
||||
bsStyle={alert.bsStyle}
|
||||
style={{ width: '500px', textAlign: 'midddle', margin: '10px auto' }}
|
||||
>
|
||||
{alert.msg}
|
||||
<i
|
||||
className="fa fa-close pull-right"
|
||||
onClick={this.removeAlert.bind(this, alert)}
|
||||
style={{ cursor: 'pointer' }}
|
||||
/>
|
||||
</Alert>
|
||||
);
|
||||
return (
|
||||
<div>{alerts}</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Alerts.propTypes = {
|
||||
alerts: React.PropTypes.array,
|
||||
actions: React.PropTypes.object,
|
||||
};
|
||||
|
||||
export default Alerts;
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
import TabbedSqlEditors from './TabbedSqlEditors';
|
||||
import QueryAutoRefresh from './QueryAutoRefresh';
|
||||
import QuerySearch from './QuerySearch';
|
||||
import Alerts from './Alerts';
|
||||
import AlertsWrapper from '../../components/AlertsWrapper';
|
||||
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
@@ -64,7 +64,7 @@ class App extends React.PureComponent {
|
||||
}
|
||||
return (
|
||||
<div className="App SqlLab">
|
||||
<Alerts id="sqllab-alerts" alerts={this.props.alerts} actions={this.props.actions} />
|
||||
<AlertsWrapper />
|
||||
<div className="container-fluid">
|
||||
{content}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import CopyToClipboard from '../../components/CopyToClipboard';
|
||||
import { getShortUrl } from '../../../utils/common';
|
||||
import { storeQuery } from '../../../utils/common';
|
||||
|
||||
const propTypes = {
|
||||
queryEditor: React.PropTypes.object.isRequired,
|
||||
@@ -9,16 +9,14 @@ const propTypes = {
|
||||
export default class CopyQueryTabUrl extends React.PureComponent {
|
||||
getUrl(callback) {
|
||||
const qe = this.props.queryEditor;
|
||||
const params = [];
|
||||
if (qe.dbId) params.push('dbid=' + qe.dbId);
|
||||
if (qe.title) params.push('title=' + encodeURIComponent(qe.title));
|
||||
if (qe.schema) params.push('schema=' + encodeURIComponent(qe.schema));
|
||||
if (qe.autorun) params.push('autorun=' + qe.autorun);
|
||||
if (qe.sql) params.push('sql=' + encodeURIComponent(qe.sql));
|
||||
|
||||
const queryString = params.join('&');
|
||||
const queryLink = window.location.pathname + '?' + queryString;
|
||||
getShortUrl(queryLink, callback);
|
||||
const sharedQuery = {
|
||||
dbId: qe.dbId,
|
||||
title: qe.title,
|
||||
schema: qe.schema,
|
||||
autorun: qe.autorun,
|
||||
sql: qe.sql,
|
||||
};
|
||||
storeQuery(sharedQuery, callback);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { connect } from 'react-redux';
|
||||
import * as Actions from '../actions';
|
||||
|
||||
const $ = require('jquery');
|
||||
const QUERY_UPDATE_FREQ = 1000;
|
||||
const QUERY_UPDATE_FREQ = 2000;
|
||||
const QUERY_UPDATE_BUFFER_MS = 5000;
|
||||
|
||||
class QueryAutoRefresh extends React.PureComponent {
|
||||
@@ -14,6 +14,14 @@ class QueryAutoRefresh extends React.PureComponent {
|
||||
componentWillUnmount() {
|
||||
this.stopTimer();
|
||||
}
|
||||
shouldCheckForQueries() {
|
||||
// if there are started or running queries, this method should return true
|
||||
const { queries } = this.props;
|
||||
const queryKeys = Object.keys(queries);
|
||||
const queriesAsArray = queryKeys.map(key => queries[key]);
|
||||
return queriesAsArray.some(q =>
|
||||
['running', 'started', 'pending', 'fetching'].indexOf(q.state) >= 0);
|
||||
}
|
||||
startTimer() {
|
||||
if (!(this.timer)) {
|
||||
this.timer = setInterval(this.stopwatch.bind(this), QUERY_UPDATE_FREQ);
|
||||
@@ -24,32 +32,29 @@ class QueryAutoRefresh extends React.PureComponent {
|
||||
this.timer = null;
|
||||
}
|
||||
stopwatch() {
|
||||
const url = '/superset/queries/' + (this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS);
|
||||
// No updates in case of failure.
|
||||
$.getJSON(url, (data) => {
|
||||
if (Object.keys(data).length > 0) {
|
||||
this.props.actions.refreshQueries(data);
|
||||
}
|
||||
this.props.actions.setNetworkStatus(true);
|
||||
})
|
||||
.fail(() => {
|
||||
this.props.actions.setNetworkStatus(false);
|
||||
});
|
||||
// only poll /superset/queries/ if there are started or running queries
|
||||
if (this.shouldCheckForQueries()) {
|
||||
const url = '/superset/queries/' + (this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS);
|
||||
$.getJSON(url, (data) => {
|
||||
if (Object.keys(data).length > 0) {
|
||||
this.props.actions.refreshQueries(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
QueryAutoRefresh.propTypes = {
|
||||
actions: React.PropTypes.object,
|
||||
queriesLastUpdate: React.PropTypes.number,
|
||||
};
|
||||
QueryAutoRefresh.defaultProps = {
|
||||
// queries: null,
|
||||
queries: React.PropTypes.object.isRequired,
|
||||
actions: React.PropTypes.object.isRequired,
|
||||
queriesLastUpdate: React.PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
queries: state.queries,
|
||||
queriesLastUpdate: state.queriesLastUpdate,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ class QuerySearch extends React.PureComponent {
|
||||
databaseId: null,
|
||||
userId: null,
|
||||
searchText: null,
|
||||
from: null,
|
||||
to: null,
|
||||
from: '28 days ago',
|
||||
to: 'now',
|
||||
status: 'success',
|
||||
queriesArray: [],
|
||||
queriesLoading: true,
|
||||
|
||||
@@ -10,7 +10,7 @@ import ModalTrigger from '../../components/ModalTrigger';
|
||||
import HighlightedSql from './HighlightedSql';
|
||||
import { STATE_BSSTYLE_MAP } from '../constants';
|
||||
import { fDuration } from '../../modules/dates';
|
||||
import { getLink } from '../../../utils/common';
|
||||
import { storeQuery } from '../../../utils/common';
|
||||
|
||||
const propTypes = {
|
||||
columns: React.PropTypes.array,
|
||||
@@ -38,10 +38,17 @@ class QueryTable extends React.PureComponent {
|
||||
activeQuery: null,
|
||||
};
|
||||
}
|
||||
getQueryLink(dbId, sql) {
|
||||
const params = ['dbid=' + dbId, 'sql=' + sql, 'title=Untitled Query'];
|
||||
const link = getLink(this.state.cleanUri, params);
|
||||
return encodeURI(link);
|
||||
callback(url) {
|
||||
window.open(url);
|
||||
}
|
||||
openQuery(dbId, schema, sql) {
|
||||
const newQuery = {
|
||||
dbId,
|
||||
title: 'Untitled Query',
|
||||
schema,
|
||||
sql,
|
||||
};
|
||||
storeQuery(newQuery, this.callback);
|
||||
}
|
||||
hideVisualizeModal() {
|
||||
this.setState({ showVisualizeModal: false });
|
||||
@@ -98,12 +105,12 @@ class QueryTable extends React.PureComponent {
|
||||
q.started = moment(q.startDttm).format('HH:mm:ss');
|
||||
q.querylink = (
|
||||
<div style={{ width: '100px' }}>
|
||||
<a
|
||||
href={this.getQueryLink(q.dbId, q.sql)}
|
||||
className="btn btn-primary btn-xs"
|
||||
<button
|
||||
className="btn btn-link btn-xs"
|
||||
onClick={this.openQuery.bind(this, q.dbId, q.schema, q.sql)}
|
||||
>
|
||||
<i className="fa fa-external-link" />Open in SQL Editor
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
q.sql = (
|
||||
@@ -133,7 +140,7 @@ class QueryTable extends React.PureComponent {
|
||||
} else {
|
||||
// if query was run using ctas and force_ctas_schema was set
|
||||
// tempTable will have the schema
|
||||
const schemaUsed = q.ctas && q.tempTable.includes('.') ? '' : q.schema;
|
||||
const schemaUsed = q.ctas && q.tempTable && q.tempTable.includes('.') ? '' : q.schema;
|
||||
q.output = [schemaUsed, q.tempTable].filter((v) => (v)).join('.');
|
||||
}
|
||||
q.progress = (
|
||||
|
||||
@@ -6,6 +6,8 @@ import shortid from 'shortid';
|
||||
import VisualizeModal from './VisualizeModal';
|
||||
import HighlightedSql from './HighlightedSql';
|
||||
|
||||
const RESULTS_CONTROLS_HEIGHT = 36;
|
||||
|
||||
const propTypes = {
|
||||
actions: React.PropTypes.object,
|
||||
csv: React.PropTypes.bool,
|
||||
@@ -34,6 +36,7 @@ class ResultSet extends React.PureComponent {
|
||||
searchText: '',
|
||||
showModal: false,
|
||||
data: [],
|
||||
resultSetHeight: '0',
|
||||
};
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
@@ -46,6 +49,10 @@ class ResultSet extends React.PureComponent {
|
||||
this.clearQueryResults(nextProps.query)
|
||||
);
|
||||
}
|
||||
if (nextProps.query.resultsKey
|
||||
&& nextProps.query.resultsKey !== this.props.query.resultsKey) {
|
||||
this.fetchResults(nextProps.query);
|
||||
}
|
||||
}
|
||||
getControls() {
|
||||
if (this.props.search || this.props.visualize || this.props.csv) {
|
||||
@@ -137,6 +144,10 @@ class ResultSet extends React.PureComponent {
|
||||
|
||||
let sql;
|
||||
|
||||
if (query.state === 'stopped') {
|
||||
return <Alert bsStyle="warning">Query was stopped</Alert>;
|
||||
}
|
||||
|
||||
if (this.props.showSql) {
|
||||
sql = <HighlightedSql sql={query.sql} />;
|
||||
}
|
||||
@@ -184,9 +195,23 @@ class ResultSet extends React.PureComponent {
|
||||
/>
|
||||
{this.getControls.bind(this)()}
|
||||
{sql}
|
||||
<div className="ResultSet">
|
||||
<div
|
||||
className="ResultSet"
|
||||
style={{ height: `${this.props.resultSetHeight - RESULTS_CONTROLS_HEIGHT}px` }}
|
||||
>
|
||||
<Table
|
||||
data={data}
|
||||
data={data.map(function (row) {
|
||||
const newRow = {};
|
||||
for (const k in row) {
|
||||
const val = row[k];
|
||||
if (typeof(val) === 'string') {
|
||||
newRow[k] = val;
|
||||
} else {
|
||||
newRow[k] = JSON.stringify(val);
|
||||
}
|
||||
}
|
||||
return newRow;
|
||||
})}
|
||||
columns={results.columns.map((col) => col.name)}
|
||||
sortable
|
||||
className="table table-condensed table-bordered"
|
||||
@@ -197,16 +222,6 @@ class ResultSet extends React.PureComponent {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (query.resultsKey) {
|
||||
return (
|
||||
<div>
|
||||
<Alert bsStyle="warning">This query was run asynchronously
|
||||
<Button bsSize="sm" onClick={this.fetchResults.bind(this, query)}>
|
||||
Fetch results
|
||||
</Button>
|
||||
</Alert>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
if (query.cached) {
|
||||
|
||||
@@ -3,12 +3,15 @@ import Button from '../../components/Button';
|
||||
|
||||
const propTypes = {
|
||||
allowAsync: PropTypes.bool.isRequired,
|
||||
dbId: PropTypes.number.isRequired,
|
||||
dbId: PropTypes.number,
|
||||
queryState: PropTypes.string.isRequired,
|
||||
runQuery: PropTypes.func.isRequired,
|
||||
selectedText: PropTypes.string,
|
||||
stopQuery: PropTypes.func.isRequired,
|
||||
};
|
||||
const defaultProps = {
|
||||
allowAsync: false,
|
||||
};
|
||||
|
||||
export default function RunQueryActionButton(props) {
|
||||
const runBtnText = props.selectedText ? 'Run Selected Query' : 'Run Query';
|
||||
@@ -28,7 +31,7 @@ export default function RunQueryActionButton(props) {
|
||||
onClick={() => props.runQuery(false)}
|
||||
key="run-btn"
|
||||
>
|
||||
<i className="fa fa-table" /> {runBtnText}
|
||||
<i className="fa fa-refresh" /> {runBtnText}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -69,3 +72,4 @@ export default function RunQueryActionButton(props) {
|
||||
}
|
||||
|
||||
RunQueryActionButton.propTypes = propTypes;
|
||||
RunQueryActionButton.defaultProps = defaultProps;
|
||||
|
||||
131
superset/assets/javascripts/SqlLab/components/SaveQuery.jsx
Normal file
@@ -0,0 +1,131 @@
|
||||
/* global notify */
|
||||
import React from 'react';
|
||||
import { FormControl, FormGroup, Overlay, Popover, Row, Col } from 'react-bootstrap';
|
||||
import Button from '../../components/Button';
|
||||
|
||||
const propTypes = {
|
||||
defaultLabel: React.PropTypes.string,
|
||||
sql: React.PropTypes.string,
|
||||
schema: React.PropTypes.string,
|
||||
dbId: React.PropTypes.number,
|
||||
animation: React.PropTypes.bool,
|
||||
onSave: React.PropTypes.func,
|
||||
};
|
||||
const defaultProps = {
|
||||
defaultLabel: 'Undefined',
|
||||
animation: true,
|
||||
onSave: () => {},
|
||||
};
|
||||
|
||||
class SaveQuery extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
description: '',
|
||||
label: props.defaultLabel,
|
||||
showSave: false,
|
||||
};
|
||||
this.toggleSave = this.toggleSave.bind(this);
|
||||
this.onSave = this.onSave.bind(this);
|
||||
this.onCancel = this.onCancel.bind(this);
|
||||
this.onLabelChange = this.onLabelChange.bind(this);
|
||||
this.onDescriptionChange = this.onDescriptionChange.bind(this);
|
||||
}
|
||||
onSave() {
|
||||
const query = {
|
||||
label: this.state.label,
|
||||
description: this.state.description,
|
||||
db_id: this.props.dbId,
|
||||
schema: this.props.schema,
|
||||
sql: this.props.sql,
|
||||
};
|
||||
this.props.onSave(query);
|
||||
this.setState({ showSave: false });
|
||||
}
|
||||
onCancel() {
|
||||
this.setState({ showSave: false });
|
||||
}
|
||||
onLabelChange(e) {
|
||||
this.setState({ label: e.target.value });
|
||||
}
|
||||
onDescriptionChange(e) {
|
||||
this.setState({ description: e.target.value });
|
||||
}
|
||||
renderPopover() {
|
||||
return (
|
||||
<Popover id="embed-code-popover">
|
||||
<FormGroup bsSize="small" style={{ width: '350px' }}>
|
||||
<Row>
|
||||
<Col md={12}>
|
||||
<small>
|
||||
<label className="control-label" htmlFor="embed-height">
|
||||
Label
|
||||
</label>
|
||||
</small>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="Label for your query"
|
||||
value={this.state.label}
|
||||
onChange={this.onLabelChange}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<br />
|
||||
<Row>
|
||||
<Col md={12}>
|
||||
<small>
|
||||
<label className="control-label" htmlFor="embed-height">Description</label>
|
||||
</small>
|
||||
<FormControl
|
||||
componentClass="textarea"
|
||||
placeholder="Write a description for your query"
|
||||
value={this.state.description}
|
||||
onChange={this.onDescriptionChange}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<br />
|
||||
<Row>
|
||||
<Col md={12}>
|
||||
<Button
|
||||
bsStyle="primary"
|
||||
onClick={this.onSave}
|
||||
className="m-r-3"
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
<Button onClick={this.onCancel} className="cancelQuery">
|
||||
Cancel
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</FormGroup>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
toggleSave(e) {
|
||||
this.setState({ target: e.target, showSave: !this.state.showSave });
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<span className="SaveQuery">
|
||||
<Overlay
|
||||
trigger="click"
|
||||
target={this.state.target}
|
||||
show={this.state.showSave}
|
||||
placement="bottom"
|
||||
animation={this.props.animation}
|
||||
>
|
||||
{this.renderPopover()}
|
||||
</Overlay>
|
||||
<Button bsSize="small" className="toggleSave" onClick={this.toggleSave}>
|
||||
<i className="fa fa-save" /> Save Query
|
||||
</Button>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
SaveQuery.propTypes = propTypes;
|
||||
SaveQuery.defaultProps = defaultProps;
|
||||
|
||||
export default SaveQuery;
|
||||
@@ -24,6 +24,36 @@ const defaultProps = {
|
||||
};
|
||||
|
||||
class SouthPane extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
innerTabHeight: this.getInnerTabHeight(),
|
||||
};
|
||||
}
|
||||
getInnerTabHeight() {
|
||||
// hack to get height the tab container so it can be fixed and scroll in place
|
||||
// calculate inner tab height
|
||||
|
||||
// document.getElementById('brace-editor').getBoundingClientRect().height;
|
||||
const sqlEditorHeight = 192;
|
||||
|
||||
// document.getElementById('js-sql-toolbar').getBoundingClientRect().height;
|
||||
const sqlToolbar = 30;
|
||||
|
||||
// document.getElementsByClassName('nav-tabs')[0].getBoundingClientRect().height * 2;
|
||||
const tabsHeight = 88;
|
||||
|
||||
// document.getElementsByTagName('header')[0].getBoundingClientRect().height;
|
||||
const headerHeight = 59;
|
||||
|
||||
const sum =
|
||||
sqlEditorHeight +
|
||||
sqlToolbar +
|
||||
tabsHeight +
|
||||
headerHeight;
|
||||
|
||||
return window.innerHeight - sum - 95;
|
||||
}
|
||||
switchTab(id) {
|
||||
this.props.actions.setActiveSouthPaneTab(id);
|
||||
}
|
||||
@@ -36,7 +66,13 @@ class SouthPane extends React.PureComponent {
|
||||
let results;
|
||||
if (latestQuery) {
|
||||
results = (
|
||||
<ResultSet showControls search query={latestQuery} actions={props.actions} />
|
||||
<ResultSet
|
||||
showControls
|
||||
search
|
||||
query={latestQuery}
|
||||
actions={props.actions}
|
||||
resultSetHeight={this.state.innerTabHeight}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
results = <Alert bsStyle="info">Run a query to display results here</Alert>;
|
||||
@@ -48,7 +84,14 @@ class SouthPane extends React.PureComponent {
|
||||
eventKey={query.id}
|
||||
key={query.id}
|
||||
>
|
||||
<ResultSet query={query} visualize={false} csv={false} actions={props.actions} cache />
|
||||
<ResultSet
|
||||
query={query}
|
||||
visualize={false}
|
||||
csv={false}
|
||||
actions={props.actions}
|
||||
cache
|
||||
resultSetHeight={this.state.innerTabHeight}
|
||||
/>
|
||||
</Tab>
|
||||
));
|
||||
|
||||
@@ -64,15 +107,15 @@ class SouthPane extends React.PureComponent {
|
||||
title="Results"
|
||||
eventKey="Results"
|
||||
>
|
||||
<div style={{ overflow: 'auto' }}>
|
||||
{results}
|
||||
</div>
|
||||
{results}
|
||||
</Tab>
|
||||
<Tab
|
||||
title="Query History"
|
||||
eventKey="History"
|
||||
>
|
||||
<QueryHistory queries={props.editorQueries} actions={props.actions} />
|
||||
<div style={{ height: `${this.state.innerTabHeight}px`, overflow: 'scroll' }}>
|
||||
<QueryHistory queries={props.editorQueries} actions={props.actions} />
|
||||
</div>
|
||||
</Tab>
|
||||
{dataPreviewTabs}
|
||||
</Tabs>
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import Button from '../../components/Button';
|
||||
|
||||
import SouthPane from './SouthPane';
|
||||
import SaveQuery from './SaveQuery';
|
||||
import Timer from '../../components/Timer';
|
||||
import SqlEditorLeftBar from './SqlEditorLeftBar';
|
||||
import AceEditorWrapper from './AceEditorWrapper';
|
||||
@@ -26,7 +27,6 @@ const propTypes = {
|
||||
height: React.PropTypes.string.isRequired,
|
||||
database: React.PropTypes.object,
|
||||
latestQuery: React.PropTypes.object,
|
||||
networkOn: React.PropTypes.bool,
|
||||
tables: React.PropTypes.array.isRequired,
|
||||
editorQueries: React.PropTypes.array.isRequired,
|
||||
dataPreviewQueries: React.PropTypes.array.isRequired,
|
||||
@@ -35,7 +35,6 @@ const propTypes = {
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
networkOn: true,
|
||||
database: null,
|
||||
latestQuery: null,
|
||||
hideLeftBar: false,
|
||||
@@ -83,7 +82,7 @@ class SqlEditor extends React.PureComponent {
|
||||
this.props.actions.setActiveSouthPaneTab('Results');
|
||||
}
|
||||
stopQuery() {
|
||||
this.props.actions.stopQuery(this.props.latestQuery);
|
||||
this.props.actions.postStopQuery(this.props.latestQuery);
|
||||
}
|
||||
createTableAs() {
|
||||
this.startQuery(true, true);
|
||||
@@ -103,6 +102,7 @@ class SqlEditor extends React.PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const qe = this.props.queryEditor;
|
||||
let limitWarning = null;
|
||||
if (this.props.latestQuery && this.props.latestQuery.limit_reached) {
|
||||
const tooltip = (
|
||||
@@ -146,17 +146,24 @@ class SqlEditor extends React.PureComponent {
|
||||
);
|
||||
}
|
||||
const editorBottomBar = (
|
||||
<div className="sql-toolbar clearfix">
|
||||
<div className="sql-toolbar clearfix" id="js-sql-toolbar">
|
||||
<div className="pull-left">
|
||||
<Form inline>
|
||||
<RunQueryActionButton
|
||||
allowAsync={this.props.database && this.props.database.allow_run_async}
|
||||
dbId={this.props.queryEditor.dbId}
|
||||
allowAsync={this.props.database ? this.props.database.allow_run_async : false}
|
||||
dbId={qe.dbId}
|
||||
queryState={this.props.latestQuery && this.props.latestQuery.state}
|
||||
runQuery={this.runQuery.bind(this)}
|
||||
selectedText={this.props.queryEditor.selectedText}
|
||||
selectedText={qe.selectedText}
|
||||
stopQuery={this.stopQuery.bind(this)}
|
||||
/>
|
||||
<SaveQuery
|
||||
defaultLabel={qe.title}
|
||||
sql={qe.sql}
|
||||
onSave={this.props.actions.saveQuery}
|
||||
schema={qe.schema}
|
||||
dbId={qe.dbId}
|
||||
/>
|
||||
{ctasControls}
|
||||
</Form>
|
||||
</div>
|
||||
@@ -190,31 +197,26 @@ class SqlEditor extends React.PureComponent {
|
||||
style={{ height: this.props.height }}
|
||||
queryEditor={this.props.queryEditor}
|
||||
tables={this.props.tables}
|
||||
networkOn={this.props.networkOn}
|
||||
actions={this.props.actions}
|
||||
/>
|
||||
</Col>
|
||||
</Collapse>
|
||||
<Col md={this.props.hideLeftBar ? 12 : 9}>
|
||||
<div className="scrollbar-container">
|
||||
<div className="scrollbar-content">
|
||||
<AceEditorWrapper
|
||||
actions={this.props.actions}
|
||||
onBlur={this.setQueryEditorSql.bind(this)}
|
||||
queryEditor={this.props.queryEditor}
|
||||
onAltEnter={this.runQuery.bind(this)}
|
||||
sql={this.props.queryEditor.sql}
|
||||
tables={this.props.tables}
|
||||
/>
|
||||
{editorBottomBar}
|
||||
<br />
|
||||
<SouthPane
|
||||
editorQueries={this.props.editorQueries}
|
||||
dataPreviewQueries={this.props.dataPreviewQueries}
|
||||
actions={this.props.actions}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<AceEditorWrapper
|
||||
actions={this.props.actions}
|
||||
onBlur={this.setQueryEditorSql.bind(this)}
|
||||
queryEditor={this.props.queryEditor}
|
||||
onAltEnter={this.runQuery.bind(this)}
|
||||
sql={this.props.queryEditor.sql}
|
||||
tables={this.props.tables}
|
||||
/>
|
||||
{editorBottomBar}
|
||||
<br />
|
||||
<SouthPane
|
||||
editorQueries={this.props.editorQueries}
|
||||
dataPreviewQueries={this.props.dataPreviewQueries}
|
||||
actions={this.props.actions}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
const $ = window.$ = require('jquery');
|
||||
import React from 'react';
|
||||
import Select from 'react-select';
|
||||
import { Label, Button } from 'react-bootstrap';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import TableElement from './TableElement';
|
||||
import AsyncSelect from '../../components/AsyncSelect';
|
||||
import Select from 'react-virtualized-select';
|
||||
import createFilterOptions from 'react-select-fast-filter-options';
|
||||
|
||||
const propTypes = {
|
||||
queryEditor: React.PropTypes.object.isRequired,
|
||||
tables: React.PropTypes.array,
|
||||
actions: React.PropTypes.object,
|
||||
networkOn: React.PropTypes.bool,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
tables: [],
|
||||
networkOn: true,
|
||||
actions: {},
|
||||
};
|
||||
|
||||
@@ -26,16 +25,16 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
schemaOptions: [],
|
||||
tableLoading: false,
|
||||
tableOptions: [],
|
||||
networkOn: true,
|
||||
};
|
||||
}
|
||||
componentWillMount() {
|
||||
this.fetchSchemas();
|
||||
this.fetchTables();
|
||||
this.fetchSchemas(this.props.queryEditor.dbId);
|
||||
this.fetchTables(this.props.queryEditor.dbId, this.props.queryEditor.schema);
|
||||
}
|
||||
onChange(db) {
|
||||
const val = (db) ? db.value : null;
|
||||
const val = db ? db.value : null;
|
||||
this.setState({ schemaOptions: [] });
|
||||
this.props.actions.queryEditorSetSchema(this.props.queryEditor, null);
|
||||
this.props.actions.queryEditorSetDb(this.props.queryEditor, val);
|
||||
if (!(db)) {
|
||||
this.setState({ tableOptions: [] });
|
||||
@@ -58,21 +57,54 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
resetState() {
|
||||
this.props.actions.resetState();
|
||||
}
|
||||
fetchTables(dbId, schema) {
|
||||
const actualDbId = dbId || this.props.queryEditor.dbId;
|
||||
if (actualDbId) {
|
||||
const actualSchema = schema || this.props.queryEditor.schema;
|
||||
this.setState({ tableLoading: true });
|
||||
this.setState({ tableOptions: [] });
|
||||
const url = `/superset/tables/${actualDbId}/${actualSchema}`;
|
||||
$.get(url, (data) => {
|
||||
let tableOptions = data.tables.map((s) => ({ value: s, label: s }));
|
||||
const views = data.views.map((s) => ({ value: s, label: '[view] ' + s }));
|
||||
tableOptions = [...tableOptions, ...views];
|
||||
this.setState({ tableOptions });
|
||||
this.setState({ tableLoading: false });
|
||||
});
|
||||
getTableNamesBySubStr(input) {
|
||||
if (!this.props.queryEditor.dbId || !input) {
|
||||
return Promise.resolve({ options: [] });
|
||||
}
|
||||
const url = `/superset/tables/${this.props.queryEditor.dbId}/` +
|
||||
`${this.props.queryEditor.schema}/${input}`;
|
||||
return $.get(url).then((data) => ({ options: data.options }));
|
||||
}
|
||||
fetchTables(dbId, schema, substr) {
|
||||
// This can be large so it shouldn't be put in the Redux store
|
||||
if (dbId && schema) {
|
||||
this.setState({ tableLoading: true, tableOptions: [] });
|
||||
const url = `/superset/tables/${dbId}/${schema}/${substr}/`;
|
||||
$.get(url, (data) => {
|
||||
const filterOptions = createFilterOptions({ options: data.options });
|
||||
this.setState({
|
||||
filterOptions,
|
||||
tableLoading: false,
|
||||
tableOptions: data.options,
|
||||
tableLength: data.tableLength,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.setState({ tableLoading: false, tableOptions: [], filterOptions: null });
|
||||
}
|
||||
}
|
||||
changeTable(tableOpt) {
|
||||
if (!tableOpt) {
|
||||
this.setState({ tableName: '' });
|
||||
return;
|
||||
}
|
||||
const namePieces = tableOpt.value.split('.');
|
||||
let tableName = namePieces[0];
|
||||
let schemaName = this.props.queryEditor.schema;
|
||||
if (namePieces.length === 1) {
|
||||
this.setState({ tableName });
|
||||
} else {
|
||||
schemaName = namePieces[0];
|
||||
tableName = namePieces[1];
|
||||
this.setState({ tableName });
|
||||
this.props.actions.queryEditorSetSchema(this.props.queryEditor, schemaName);
|
||||
this.fetchTables(this.props.queryEditor.dbId, schemaName);
|
||||
}
|
||||
this.setState({ tableLoading: true });
|
||||
// TODO: handle setting the tableLoading state depending on success or
|
||||
// failure of the addTable async call in the action.
|
||||
this.props.actions.addTable(this.props.queryEditor, tableName, schemaName);
|
||||
this.setState({ tableLoading: false });
|
||||
}
|
||||
changeSchema(schemaOpt) {
|
||||
const schema = (schemaOpt) ? schemaOpt.value : null;
|
||||
@@ -83,10 +115,9 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
const actualDbId = dbId || this.props.queryEditor.dbId;
|
||||
if (actualDbId) {
|
||||
this.setState({ schemaLoading: true });
|
||||
const url = `/databasetablesasync/api/read?_flt_0_id=${actualDbId}`;
|
||||
const url = `/superset/schemas/${actualDbId}/`;
|
||||
$.get(url, (data) => {
|
||||
const schemas = data.result[0].all_schema_names;
|
||||
const schemaOptions = schemas.map((s) => ({ value: s, label: s }));
|
||||
const schemaOptions = data.schemas.map((s) => ({ value: s, label: s }));
|
||||
this.setState({ schemaOptions });
|
||||
this.setState({ schemaLoading: false });
|
||||
});
|
||||
@@ -95,29 +126,18 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
closePopover(ref) {
|
||||
this.refs[ref].hide();
|
||||
}
|
||||
changeTable(tableOpt) {
|
||||
const tableName = tableOpt.value;
|
||||
const qe = this.props.queryEditor;
|
||||
|
||||
this.setState({ tableLoading: true });
|
||||
this.props.actions.addTable(qe, tableName);
|
||||
this.setState({ tableLoading: false });
|
||||
}
|
||||
render() {
|
||||
let networkAlert = null;
|
||||
if (!this.props.networkOn) {
|
||||
networkAlert = <p><Label bsStyle="danger">OFFLINE</Label></p>;
|
||||
}
|
||||
const shouldShowReset = window.location.search === '?reset=1';
|
||||
return (
|
||||
<div className="scrollbar-container">
|
||||
<div className="clearfix sql-toolbar scrollbar-content">
|
||||
{networkAlert}
|
||||
<div>
|
||||
<AsyncSelect
|
||||
dataEndpoint="/databaseasync/api/read?_flt_0_expose_in_sqllab=1"
|
||||
onChange={this.onChange.bind(this)}
|
||||
value={this.props.queryEditor.dbId}
|
||||
databaseId={this.props.queryEditor.dbId}
|
||||
actions={this.props.actions}
|
||||
valueRenderer={(o) => (
|
||||
<div>
|
||||
<span className="text-muted">Database:</span> {o.label}
|
||||
@@ -144,15 +164,31 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
/>
|
||||
</div>
|
||||
<div className="m-t-5">
|
||||
<Select
|
||||
name="select-table"
|
||||
ref="selectTable"
|
||||
isLoading={this.state.tableLoading}
|
||||
placeholder={`Add a table (${this.state.tableOptions.length})`}
|
||||
autosize={false}
|
||||
onChange={this.changeTable.bind(this)}
|
||||
options={this.state.tableOptions}
|
||||
/>
|
||||
{this.props.queryEditor.schema &&
|
||||
<Select
|
||||
name="select-table"
|
||||
ref="selectTable"
|
||||
isLoading={this.state.tableLoading}
|
||||
value={this.state.tableName}
|
||||
placeholder={`Add a table (${this.state.tableOptions.length})`}
|
||||
autosize={false}
|
||||
onChange={this.changeTable.bind(this)}
|
||||
filterOptions={this.state.filterOptions}
|
||||
options={this.state.tableOptions}
|
||||
/>
|
||||
}
|
||||
{!this.props.queryEditor.schema &&
|
||||
<Select
|
||||
async
|
||||
name="async-select-table"
|
||||
ref="selectTable"
|
||||
value={this.state.tableName}
|
||||
placeholder={"Type to search ..."}
|
||||
autosize={false}
|
||||
onChange={this.changeTable.bind(this)}
|
||||
loadOptions={this.getTableNamesBySubStr.bind(this)}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<hr />
|
||||
<div className="m-t-5">
|
||||
|
||||
@@ -4,9 +4,9 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import * as Actions from '../actions';
|
||||
import SqlEditor from './SqlEditor';
|
||||
import { getParamFromQuery } from '../../../utils/common';
|
||||
import CopyQueryTabUrl from './CopyQueryTabUrl';
|
||||
import { areArraysShallowEqual } from '../../reduxUtils';
|
||||
import URI from 'urijs';
|
||||
|
||||
const propTypes = {
|
||||
actions: React.PropTypes.object.isRequired,
|
||||
@@ -15,12 +15,10 @@ const propTypes = {
|
||||
queryEditors: React.PropTypes.array,
|
||||
tabHistory: React.PropTypes.array.isRequired,
|
||||
tables: React.PropTypes.array.isRequired,
|
||||
networkOn: React.PropTypes.bool,
|
||||
editorHeight: React.PropTypes.string.isRequired,
|
||||
};
|
||||
const defaultProps = {
|
||||
queryEditors: [],
|
||||
networkOn: true,
|
||||
};
|
||||
|
||||
let queryCount = 1;
|
||||
@@ -28,34 +26,53 @@ let queryCount = 1;
|
||||
class TabbedSqlEditors extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const uri = window.location.toString();
|
||||
const search = window.location.search;
|
||||
const cleanUri = search ? uri.substring(0, uri.indexOf('?')) : uri;
|
||||
const query = search.substring(1);
|
||||
const sqlLabUrl = '/superset/sqllab';
|
||||
this.state = {
|
||||
uri,
|
||||
cleanUri,
|
||||
query,
|
||||
sqlLabUrl,
|
||||
queriesArray: [],
|
||||
dataPreviewQueries: [],
|
||||
hideLeftBar: false,
|
||||
};
|
||||
}
|
||||
componentWillMount() {
|
||||
if (this.state.query) {
|
||||
queryCount++;
|
||||
const queryEditorProps = {
|
||||
title: getParamFromQuery(this.state.query, 'title'),
|
||||
dbId: parseInt(getParamFromQuery(this.state.query, 'dbid'), 10),
|
||||
schema: getParamFromQuery(this.state.query, 'schema'),
|
||||
autorun: getParamFromQuery(this.state.query, 'autorun'),
|
||||
sql: getParamFromQuery(this.state.query, 'sql'),
|
||||
};
|
||||
this.props.actions.addQueryEditor(queryEditorProps);
|
||||
// Clean the url in browser history
|
||||
window.history.replaceState({}, document.title, this.state.cleanUri);
|
||||
componentDidMount() {
|
||||
const query = URI(window.location).search(true);
|
||||
if (query.id || query.sql || query.savedQueryId) {
|
||||
if (query.id) {
|
||||
this.props.actions.popStoredQuery(query.id);
|
||||
} else if (query.savedQueryId) {
|
||||
this.props.actions.popSavedQuery(query.savedQueryId);
|
||||
} else if (query.sql) {
|
||||
let dbId = query.dbid;
|
||||
if (dbId) {
|
||||
dbId = parseInt(dbId, 10);
|
||||
} else {
|
||||
const databases = this.props.databases;
|
||||
const dbName = query.dbname;
|
||||
if (dbName) {
|
||||
Object.keys(databases).forEach((db) => {
|
||||
if (databases[db].database_name === dbName) {
|
||||
dbId = databases[db].id;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
const newQueryEditor = {
|
||||
title: query.title,
|
||||
dbId,
|
||||
schema: query.schema,
|
||||
autorun: query.autorun,
|
||||
sql: query.sql,
|
||||
};
|
||||
this.props.actions.addQueryEditor(newQueryEditor);
|
||||
}
|
||||
this.popNewTab();
|
||||
}
|
||||
}
|
||||
popNewTab() {
|
||||
queryCount++;
|
||||
// Clean the url in browser history
|
||||
window.history.replaceState({}, document.title, this.state.sqlLabUrl);
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const nextActiveQeId = nextProps.tabHistory[nextProps.tabHistory.length - 1];
|
||||
const queriesArray = [];
|
||||
@@ -180,7 +197,6 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||
latestQuery={latestQuery}
|
||||
database={database}
|
||||
actions={this.props.actions}
|
||||
networkOn={this.props.networkOn}
|
||||
hideLeftBar={this.state.hideLeftBar}
|
||||
/>
|
||||
}
|
||||
@@ -216,7 +232,6 @@ function mapStateToProps(state) {
|
||||
queryEditors: state.queryEditors,
|
||||
queries: state.queries,
|
||||
tabHistory: state.tabHistory,
|
||||
networkOn: state.networkOn,
|
||||
tables: state.tables,
|
||||
defaultDbId: state.defaultDbId,
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* global notify */
|
||||
import React from 'react';
|
||||
import { Alert, Button, Col, Modal } from 'react-bootstrap';
|
||||
|
||||
@@ -5,6 +6,7 @@ import Select from 'react-select';
|
||||
import { Table } from 'reactable';
|
||||
import shortid from 'shortid';
|
||||
import $ from 'jquery';
|
||||
import { getExploreUrl } from '../../explorev2/exploreUtils';
|
||||
|
||||
const CHART_TYPES = [
|
||||
{ value: 'dist_bar', label: 'Distribution - Bar Chart', requiresTime: false },
|
||||
@@ -27,10 +29,9 @@ const defaultProps = {
|
||||
class VisualizeModal extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const uniqueId = shortid.generate();
|
||||
this.state = {
|
||||
chartType: CHART_TYPES[0],
|
||||
datasourceName: uniqueId,
|
||||
datasourceName: this.datasourceName(),
|
||||
columns: {},
|
||||
hints: [],
|
||||
};
|
||||
@@ -54,6 +55,17 @@ class VisualizeModal extends React.PureComponent {
|
||||
});
|
||||
this.setState({ columns });
|
||||
}
|
||||
datasourceName() {
|
||||
const { query } = this.props;
|
||||
const uniqueId = shortid.generate();
|
||||
let datasourceName = uniqueId;
|
||||
if (query) {
|
||||
datasourceName = query.user ? `${query.user}-` : '';
|
||||
datasourceName += query.db ? `${query.db}-` : '';
|
||||
datasourceName += `${query.tab}-${uniqueId}`;
|
||||
}
|
||||
return datasourceName;
|
||||
}
|
||||
validate() {
|
||||
const hints = [];
|
||||
const cols = this.mergedColumns();
|
||||
@@ -79,7 +91,9 @@ class VisualizeModal extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
if (!hasTime) {
|
||||
hints.push('To use this chart type you need at least one column flagged as a date');
|
||||
hints.push(
|
||||
'To use this chart type you need at least one column ' +
|
||||
'flagged as a date');
|
||||
}
|
||||
}
|
||||
this.setState({ hints });
|
||||
@@ -106,6 +120,7 @@ class VisualizeModal extends React.PureComponent {
|
||||
sql: this.props.query.sql,
|
||||
dbId: this.props.query.dbId,
|
||||
};
|
||||
notify.info('Creating a data source and popping a new tab');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/superset/sqllab_viz/',
|
||||
@@ -113,9 +128,28 @@ class VisualizeModal extends React.PureComponent {
|
||||
data: {
|
||||
data: JSON.stringify(vizOptions),
|
||||
},
|
||||
success: (url) => {
|
||||
window.open(url);
|
||||
dataType: 'json',
|
||||
success: resp => {
|
||||
const columns = Object.keys(this.state.columns).map(k => this.state.columns[k]);
|
||||
const data = JSON.parse(resp);
|
||||
const mainMetric = columns.filter(d => d.agg)[0];
|
||||
const mainGroupBy = columns.filter(d => d.is_dim)[0];
|
||||
const formData = {
|
||||
datasource: `${data.table_id}__table`,
|
||||
viz_type: this.state.chartType.value,
|
||||
since: '100 years ago',
|
||||
limit: '0',
|
||||
};
|
||||
if (mainMetric) {
|
||||
formData.metrics = [mainMetric.name];
|
||||
formData.metric = mainMetric.name;
|
||||
}
|
||||
if (mainGroupBy) {
|
||||
formData.groupby = mainGroupBy.name;
|
||||
}
|
||||
window.open(getExploreUrl(formData));
|
||||
},
|
||||
error: () => notify('An error occurred while creating the data source'),
|
||||
});
|
||||
}
|
||||
changeDatasourceName(event) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { getInitialState, sqlLabReducer } from './reducers';
|
||||
import { initEnhancer } from '../reduxUtils';
|
||||
import { initJQueryAjaxCSRF } from '../modules/utils';
|
||||
import { createStore, compose, applyMiddleware } from 'redux';
|
||||
import { Provider } from 'react-redux';
|
||||
import thunkMiddleware from 'redux-thunk';
|
||||
@@ -14,6 +15,7 @@ import App from './components/App';
|
||||
|
||||
|
||||
require('./main.css');
|
||||
initJQueryAjaxCSRF();
|
||||
|
||||
const appContainer = document.getElementById('app');
|
||||
const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap'));
|
||||
|
||||
@@ -237,7 +237,16 @@ div.tablePopover:hover {
|
||||
padding-bottom: 3px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.ResultSet {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.ResultSet table {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.ResultSet table tr.last {
|
||||
border-bottom: none;
|
||||
}
|
||||
.ace_editor {
|
||||
border: 1px solid #ccc;
|
||||
margin: 0px 0px 10px 0px;
|
||||
|
||||
@@ -17,7 +17,6 @@ export function getInitialState(defaultDbId) {
|
||||
|
||||
return {
|
||||
alerts: [],
|
||||
networkOn: true,
|
||||
queries: {},
|
||||
databases: {},
|
||||
queryEditors: [defaultQueryEditor],
|
||||
@@ -151,7 +150,7 @@ export const sqlLabReducer = function (state, action) {
|
||||
return alterInArr(newState, 'queryEditors', sqlEditor, { latestQueryId: action.query.id });
|
||||
},
|
||||
[actions.STOP_QUERY]() {
|
||||
return alterInObject(state, 'queries', action.query, { state: 'stopped' });
|
||||
return alterInObject(state, 'queries', action.query, { state: 'stopped', results: [] });
|
||||
},
|
||||
[actions.CLEAR_QUERY_RESULTS]() {
|
||||
const newResults = Object.assign({}, action.query.results);
|
||||
@@ -162,6 +161,9 @@ export const sqlLabReducer = function (state, action) {
|
||||
return alterInObject(state, 'queries', action.query, { state: 'fetching' });
|
||||
},
|
||||
[actions.QUERY_SUCCESS]() {
|
||||
if (action.query.state === 'stopped') {
|
||||
return state;
|
||||
}
|
||||
let rows;
|
||||
if (action.results.data) {
|
||||
rows = action.results.data.length;
|
||||
@@ -178,6 +180,9 @@ export const sqlLabReducer = function (state, action) {
|
||||
return alterInObject(state, 'queries', action.query, alts);
|
||||
},
|
||||
[actions.QUERY_FAILED]() {
|
||||
if (action.query.state === 'stopped') {
|
||||
return state;
|
||||
}
|
||||
const alts = { state: 'failed', errorMessage: action.msg, endDttm: now() };
|
||||
return alterInObject(state, 'queries', action.query, alts);
|
||||
},
|
||||
@@ -224,21 +229,15 @@ export const sqlLabReducer = function (state, action) {
|
||||
[actions.REMOVE_ALERT]() {
|
||||
return removeFromArr(state, 'alerts', action.alert);
|
||||
},
|
||||
[actions.SET_NETWORK_STATUS]() {
|
||||
if (state.networkOn !== action.networkOn) {
|
||||
return Object.assign({}, state, { networkOn: action.networkOn });
|
||||
}
|
||||
return state;
|
||||
},
|
||||
[actions.REFRESH_QUERIES]() {
|
||||
let newQueries = Object.assign({}, state.queries);
|
||||
// Fetch the updates to the queries present in the store.
|
||||
let change = false;
|
||||
for (const id in action.alteredQueries) {
|
||||
const changedQuery = action.alteredQueries[id];
|
||||
if (
|
||||
!state.queries.hasOwnProperty(id) ||
|
||||
state.queries[id].changedOn !== changedQuery.changedOn) {
|
||||
if (!state.queries.hasOwnProperty(id) ||
|
||||
(state.queries[id].changedOn !== changedQuery.changedOn &&
|
||||
state.queries[id].state !== 'stopped')) {
|
||||
newQueries[id] = Object.assign({}, state.queries[id], changedQuery);
|
||||
change = true;
|
||||
}
|
||||
|
||||
18
superset/assets/javascripts/components/AlertsWrapper.jsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import AlertContainer from 'react-alert';
|
||||
|
||||
export default class AlertsWrapper extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<AlertContainer
|
||||
ref={ref => {
|
||||
global.notify = ref;
|
||||
}}
|
||||
offset={14}
|
||||
position="top right"
|
||||
theme="dark"
|
||||
time={5000}
|
||||
transition="fade"
|
||||
/>);
|
||||
}
|
||||
}
|
||||