mirror of https://github.com/apache/superset.git
[adhoc-filters] Adding adhoc-filters to all viz types (#5206)
This commit is contained in:
parent
1fc4ee0d3c
commit
d483ed121c
|
@ -0,0 +1,743 @@
|
|||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||
"requires": {
|
||||
"chalk": "^1.1.3",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"babel-helper-builder-binary-assignment-operator-visitor": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
|
||||
"integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-explode-assignable-expression": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-call-delegate": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
|
||||
"integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
|
||||
"requires": {
|
||||
"babel-helper-hoist-variables": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-define-map": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
|
||||
"integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
|
||||
"requires": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"babel-helper-explode-assignable-expression": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
|
||||
"integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-function-name": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
|
||||
"integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
|
||||
"requires": {
|
||||
"babel-helper-get-function-arity": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-get-function-arity": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
|
||||
"integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-hoist-variables": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
|
||||
"integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-optimise-call-expression": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
|
||||
"integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-regex": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
|
||||
"integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"babel-helper-remap-async-to-generator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
|
||||
"integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-replace-supers": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
||||
"integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
|
||||
"requires": {
|
||||
"babel-helper-optimise-call-expression": "^6.24.1",
|
||||
"babel-messages": "^6.23.0",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-messages": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
|
||||
"integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-check-es2015-constants": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
|
||||
"integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-dynamic-import-node": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.2.0.tgz",
|
||||
"integrity": "sha512-yeDwKaLgGdTpXL7RgGt5r6T4LmnTza/hUn5Ul8uZSGGMtEjYo13Nxai7SQaGCTEzUtg9Zq9qJn0EjEr7SeSlTQ==",
|
||||
"requires": {
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-syntax-async-functions": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
|
||||
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-dynamic-import": {
|
||||
"version": "6.18.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
|
||||
"integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo="
|
||||
},
|
||||
"babel-plugin-syntax-exponentiation-operator": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
|
||||
"integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-trailing-function-commas": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
|
||||
"integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-transform-async-to-generator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
|
||||
"integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-remap-async-to-generator": "^6.24.1",
|
||||
"babel-plugin-syntax-async-functions": "^6.8.0",
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-arrow-functions": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
||||
"integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
|
||||
"integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-block-scoping": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
|
||||
"integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-template": "^6.26.0",
|
||||
"babel-traverse": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-classes": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
|
||||
"integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
|
||||
"requires": {
|
||||
"babel-helper-define-map": "^6.24.1",
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-helper-optimise-call-expression": "^6.24.1",
|
||||
"babel-helper-replace-supers": "^6.24.1",
|
||||
"babel-messages": "^6.23.0",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-computed-properties": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
|
||||
"integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-destructuring": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
|
||||
"integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-duplicate-keys": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
|
||||
"integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-for-of": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
|
||||
"integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-function-name": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
|
||||
"integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
|
||||
"requires": {
|
||||
"babel-helper-function-name": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-literals": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
|
||||
"integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-modules-amd": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
|
||||
"integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
|
||||
"requires": {
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-modules-commonjs": {
|
||||
"version": "6.26.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
|
||||
"integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
|
||||
"requires": {
|
||||
"babel-plugin-transform-strict-mode": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-template": "^6.26.0",
|
||||
"babel-types": "^6.26.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-modules-systemjs": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
|
||||
"integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
|
||||
"requires": {
|
||||
"babel-helper-hoist-variables": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-modules-umd": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
|
||||
"integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
|
||||
"requires": {
|
||||
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-object-super": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
|
||||
"integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
|
||||
"requires": {
|
||||
"babel-helper-replace-supers": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-parameters": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
|
||||
"integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
|
||||
"requires": {
|
||||
"babel-helper-call-delegate": "^6.24.1",
|
||||
"babel-helper-get-function-arity": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-shorthand-properties": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
|
||||
"integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-spread": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
|
||||
"integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-sticky-regex": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
|
||||
"integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
|
||||
"requires": {
|
||||
"babel-helper-regex": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-template-literals": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
|
||||
"integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-typeof-symbol": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
|
||||
"integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-unicode-regex": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
|
||||
"integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
|
||||
"requires": {
|
||||
"babel-helper-regex": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"regexpu-core": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-exponentiation-operator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
|
||||
"integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
|
||||
"babel-plugin-syntax-exponentiation-operator": "^6.8.0",
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-regenerator": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
|
||||
"integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
|
||||
"requires": {
|
||||
"regenerator-transform": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-strict-mode": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
|
||||
"integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-preset-env": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
|
||||
"integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-plugin-check-es2015-constants": "^6.22.0",
|
||||
"babel-plugin-syntax-trailing-function-commas": "^6.22.0",
|
||||
"babel-plugin-transform-async-to-generator": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoping": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-classes": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-computed-properties": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-for-of": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-function-name": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-amd": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-modules-umd": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-object-super": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-parameters": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
|
||||
"babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
|
||||
"babel-plugin-transform-exponentiation-operator": "^6.22.0",
|
||||
"babel-plugin-transform-regenerator": "^6.22.0",
|
||||
"browserslist": "^3.2.6",
|
||||
"invariant": "^2.2.2",
|
||||
"semver": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"babel-preset-es2015": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz",
|
||||
"integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=",
|
||||
"requires": {
|
||||
"babel-plugin-check-es2015-constants": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoping": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-classes": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-computed-properties": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-destructuring": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-duplicate-keys": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-for-of": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-function-name": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-modules-systemjs": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-object-super": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-parameters": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-shorthand-properties": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-sticky-regex": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-typeof-symbol": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-unicode-regex": "^6.24.1",
|
||||
"babel-plugin-transform-regenerator": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-runtime": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
||||
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
||||
"requires": {
|
||||
"core-js": "^2.4.0",
|
||||
"regenerator-runtime": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"babel-template": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
|
||||
"integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-traverse": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"babylon": "^6.18.0",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"babel-traverse": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
|
||||
"integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
|
||||
"requires": {
|
||||
"babel-code-frame": "^6.26.0",
|
||||
"babel-messages": "^6.23.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"babel-types": "^6.26.0",
|
||||
"babylon": "^6.18.0",
|
||||
"debug": "^2.6.8",
|
||||
"globals": "^9.18.0",
|
||||
"invariant": "^2.2.2",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"babel-types": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
|
||||
"integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"esutils": "^2.0.2",
|
||||
"lodash": "^4.17.4",
|
||||
"to-fast-properties": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"babylon": {
|
||||
"version": "6.18.0",
|
||||
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
|
||||
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "3.2.8",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
|
||||
"integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30000844",
|
||||
"electron-to-chromium": "^1.3.47"
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30000856",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000856.tgz",
|
||||
"integrity": "sha512-x3mYcApHMQemyaHuH/RyqtKCGIYTgEA63fdi+VBvDz8xUSmRiVWTLeyKcoGQCGG6UPR9/+4qG4OKrTa6aSQRKg==",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "2.5.7",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
|
||||
"integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.48",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz",
|
||||
"integrity": "sha1-07DYWTgUBE4JLs4hCPw6ya6kuQA=",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
|
||||
},
|
||||
"globals": {
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
|
||||
"integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
|
||||
},
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.10",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
|
||||
"integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"private": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
|
||||
"integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
|
||||
"integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg=="
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
||||
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
|
||||
},
|
||||
"regenerator-transform": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
|
||||
"integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.18.0",
|
||||
"babel-types": "^6.19.0",
|
||||
"private": "^0.1.6"
|
||||
}
|
||||
},
|
||||
"regexpu-core": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
|
||||
"integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
|
||||
"requires": {
|
||||
"regenerate": "^1.2.1",
|
||||
"regjsgen": "^0.2.0",
|
||||
"regjsparser": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"regjsgen": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
|
||||
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc="
|
||||
},
|
||||
"regjsparser": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
|
||||
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
|
||||
"requires": {
|
||||
"jsesc": "~0.5.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
|
||||
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1683,18 +1683,6 @@
|
|||
"renderTrigger": true,
|
||||
"default": ""
|
||||
},
|
||||
"where": {
|
||||
"type": "TextControl",
|
||||
"label": "Custom WHERE clause",
|
||||
"default": "",
|
||||
"description": "The text in this box gets included in your query's WHERE clause, as an AND to other criteria. You can include complex expression, parenthesis and anything else supported by the backend it is directed towards."
|
||||
},
|
||||
"having": {
|
||||
"type": "TextControl",
|
||||
"label": "Custom HAVING clause",
|
||||
"default": "",
|
||||
"description": "The text in this box gets included in your query's HAVING clause, as an AND to other criteria. You can include complex expression, parenthesis and anything else supported by the backend it is directed towards."
|
||||
},
|
||||
"compare_lag": {
|
||||
"type": "TextControl",
|
||||
"label": "Comparison Period Lag",
|
||||
|
@ -2628,12 +2616,6 @@
|
|||
"default": "",
|
||||
"description": "Labels for the marker lines"
|
||||
},
|
||||
"filters": {
|
||||
"type": "FilterControl",
|
||||
"label": "",
|
||||
"default": [],
|
||||
"description": ""
|
||||
},
|
||||
"annotation_layers": {
|
||||
"type": "AnnotationLayerControl",
|
||||
"label": "",
|
||||
|
@ -2641,12 +2623,6 @@
|
|||
"description": "Annotation Layers",
|
||||
"renderTrigger": true
|
||||
},
|
||||
"having_filters": {
|
||||
"type": "FilterControl",
|
||||
"label": "",
|
||||
"default": [],
|
||||
"description": ""
|
||||
},
|
||||
"slice_id": {
|
||||
"type": "HiddenControl",
|
||||
"label": "Slice ID",
|
||||
|
|
|
@ -11,7 +11,15 @@ import TooltipWrapper from '../../../src/components/TooltipWrapper';
|
|||
|
||||
const defaultProps = {
|
||||
origFormData: {
|
||||
filters: [{ col: 'a', op: '==', val: 'hello' }],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'hello',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
subject: 'a',
|
||||
},
|
||||
],
|
||||
y_axis_bounds: [10, 20],
|
||||
column_collection: [{ 1: 'a', b: ['6', 'g'] }],
|
||||
bool: false,
|
||||
|
@ -21,7 +29,15 @@ const defaultProps = {
|
|||
ever: { a: 'b', c: 'd' },
|
||||
},
|
||||
currentFormData: {
|
||||
filters: [{ col: 'b', op: 'in', val: ['hello', 'my', 'name'] }],
|
||||
adhoc_filters: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: ['hello', 'my', 'name'],
|
||||
expressionType: 'SIMPLE',
|
||||
operator: 'in',
|
||||
subject: 'b',
|
||||
},
|
||||
],
|
||||
y_axis_bounds: [15, 16],
|
||||
column_collection: [{ 1: 'a', b: [9, '15'], t: 'gggg' }],
|
||||
bool: true,
|
||||
|
@ -33,9 +49,25 @@ const defaultProps = {
|
|||
};
|
||||
|
||||
const expectedDiffs = {
|
||||
filters: {
|
||||
before: [{ col: 'a', op: '==', val: 'hello' }],
|
||||
after: [{ col: 'b', op: 'in', val: ['hello', 'my', 'name'] }],
|
||||
adhoc_filters: {
|
||||
before: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'hello',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
subject: 'a',
|
||||
},
|
||||
],
|
||||
after: [
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: ['hello', 'my', 'name'],
|
||||
expressionType: 'SIMPLE',
|
||||
operator: 'in',
|
||||
subject: 'b',
|
||||
},
|
||||
],
|
||||
},
|
||||
y_axis_bounds: {
|
||||
before: [10, 20],
|
||||
|
@ -211,25 +243,49 @@ describe('AlteredSliceTag', () => {
|
|||
});
|
||||
|
||||
it('returns "[]" for empty filters', () => {
|
||||
expect(wrapper.instance().formatValue([], 'filters')).to.equal('[]');
|
||||
expect(wrapper.instance().formatValue([], 'adhoc_filters')).to.equal('[]');
|
||||
});
|
||||
|
||||
it('correctly formats filters with array values', () => {
|
||||
const filters = [
|
||||
{ col: 'a', op: 'in', val: ['1', 'g', '7', 'ho'] },
|
||||
{ col: 'b', op: 'not in', val: ['hu', 'ho', 'ha'] },
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: ['1', 'g', '7', 'ho'],
|
||||
expressionType: 'SIMPLE',
|
||||
operator: 'in',
|
||||
subject: 'a',
|
||||
},
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: ['hu', 'ho', 'ha'],
|
||||
expressionType: 'SIMPLE',
|
||||
operator: 'not in',
|
||||
subject: 'b',
|
||||
},
|
||||
];
|
||||
const expected = 'a in [1, g, 7, ho], b not in [hu, ho, ha]';
|
||||
expect(wrapper.instance().formatValue(filters, 'filters')).to.equal(expected);
|
||||
expect(wrapper.instance().formatValue(filters, 'adhoc_filters')).to.equal(expected);
|
||||
});
|
||||
|
||||
it('correctly formats filters with string values', () => {
|
||||
const filters = [
|
||||
{ col: 'a', op: '==', val: 'gucci' },
|
||||
{ col: 'b', op: 'LIKE', val: 'moshi moshi' },
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'gucci',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '==',
|
||||
subject: 'a',
|
||||
},
|
||||
{
|
||||
clause: 'WHERE',
|
||||
comparator: 'moshi moshi',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: 'LIKE',
|
||||
subject: 'b',
|
||||
},
|
||||
];
|
||||
const expected = 'a == gucci, b LIKE moshi moshi';
|
||||
expect(wrapper.instance().formatValue(filters, 'filters')).to.equal(expected);
|
||||
expect(wrapper.instance().formatValue(filters, 'adhoc_filters')).to.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -33,18 +33,9 @@ const columns = [
|
|||
{ type: 'DOUBLE', column_name: 'value' },
|
||||
];
|
||||
|
||||
const legacyFilter = { col: 'value', op: '>', val: '5' };
|
||||
const legacyHavingFilter = { col: 'SUM(value)', op: '>', val: '10' };
|
||||
const whereFilterText = 'target in (\'alpha\')';
|
||||
const havingFilterText = 'SUM(value) < 20';
|
||||
|
||||
const formData = {
|
||||
filters: [legacyFilter],
|
||||
having: havingFilterText,
|
||||
having_filters: [legacyHavingFilter],
|
||||
metric: undefined,
|
||||
metrics: [sumValueAdhocMetric, savedMetric.saved_metric_name],
|
||||
where: whereFilterText,
|
||||
};
|
||||
|
||||
function setup(overrides) {
|
||||
|
@ -68,49 +59,6 @@ describe('AdhocFilterControl', () => {
|
|||
expect(wrapper.find(OnPasteSelect)).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('will translate legacy filters into adhoc filters if no adhoc filters are present', () => {
|
||||
const { wrapper } = setup({ value: undefined });
|
||||
expect(wrapper.state('values')).to.have.lengthOf(4);
|
||||
expect(wrapper.state('values')[0].equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: 'value',
|
||||
operator: '>',
|
||||
comparator: '5',
|
||||
clause: CLAUSES.WHERE,
|
||||
})
|
||||
))).to.be.true;
|
||||
expect(wrapper.state('values')[1].equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: 'SUM(value)',
|
||||
operator: '>',
|
||||
comparator: '10',
|
||||
clause: CLAUSES.HAVING,
|
||||
})
|
||||
))).to.be.true;
|
||||
expect(wrapper.state('values')[2].equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'target in (\'alpha\')',
|
||||
clause: CLAUSES.WHERE,
|
||||
})
|
||||
))).to.be.true;
|
||||
expect(wrapper.state('values')[3].equals((
|
||||
new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
sqlExpression: 'SUM(value) < 20',
|
||||
clause: CLAUSES.HAVING,
|
||||
})
|
||||
))).to.be.true;
|
||||
});
|
||||
|
||||
it('will ignore legacy filters if adhoc filters are present', () => {
|
||||
const { wrapper } = setup();
|
||||
expect(wrapper.state('values')).to.have.lengthOf(1);
|
||||
expect(wrapper.state('values')[0]).to.equal(simpleAdhocFilter);
|
||||
});
|
||||
|
||||
it('handles saved metrics being selected to filter on', () => {
|
||||
const { wrapper, onChange } = setup({ value: [] });
|
||||
const select = wrapper.find(OnPasteSelect);
|
||||
|
|
|
@ -26,6 +26,6 @@ describe('ControlPanelsContainer', () => {
|
|||
});
|
||||
|
||||
it('renders ControlPanelSections', () => {
|
||||
expect(wrapper.find(ControlPanelSection)).to.have.lengthOf(7);
|
||||
expect(wrapper.find(ControlPanelSection)).to.have.lengthOf(6);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,248 +0,0 @@
|
|||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import sinon from 'sinon';
|
||||
import { expect } from 'chai';
|
||||
import { describe, it, beforeEach } from 'mocha';
|
||||
import { shallow } from 'enzyme';
|
||||
import FilterControl from '../../../../src/explore/components/controls/FilterControl';
|
||||
import Filter from '../../../../src/explore/components/controls/Filter';
|
||||
|
||||
const $ = window.$ = require('jquery');
|
||||
|
||||
const defaultProps = {
|
||||
name: 'not_having_filters',
|
||||
onChange: sinon.spy(),
|
||||
value: [
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: ['a', 'b', 'd'],
|
||||
},
|
||||
{
|
||||
col: 'col2',
|
||||
op: '==',
|
||||
val: 'Z',
|
||||
},
|
||||
],
|
||||
datasource: {
|
||||
id: 1,
|
||||
type: 'qtable',
|
||||
filter_select: true,
|
||||
filterable_cols: [['col1', 'col2']],
|
||||
metrics_combo: [
|
||||
['m1', 'v1'],
|
||||
['m2', 'v2'],
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
describe('FilterControl', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<FilterControl {...defaultProps} />);
|
||||
wrapper.setState({
|
||||
filters: [
|
||||
{
|
||||
valuesLoading: false,
|
||||
valueChoices: ['a', 'b', 'c', 'd', 'e', 'f'],
|
||||
},
|
||||
{
|
||||
valuesLoading: false,
|
||||
valueChoices: ['X', 'Y', 'Z'],
|
||||
},
|
||||
// Need a duplicate since onChange calls are not changing props
|
||||
{
|
||||
valuesLoading: false,
|
||||
valueChoices: ['X', 'Y', 'Z'],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('renders Filters', () => {
|
||||
expect(
|
||||
React.isValidElement(<FilterControl {...defaultProps} />),
|
||||
).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders one button and two filters', () => {
|
||||
expect(wrapper.find(Filter)).to.have.lengthOf(2);
|
||||
expect(wrapper.find(Button)).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('adds filter when clicking Add Filter', () => {
|
||||
const addButton = wrapper.find('#add-button');
|
||||
expect(addButton).to.have.lengthOf(1);
|
||||
addButton.simulate('click');
|
||||
expect(defaultProps.onChange).to.have.property('callCount', 1);
|
||||
expect(defaultProps.onChange.getCall(0).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: ['a', 'b', 'd'],
|
||||
},
|
||||
{
|
||||
col: 'col2',
|
||||
op: '==',
|
||||
val: 'Z',
|
||||
},
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: [],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('removes a the second filter when its delete button is clicked', () => {
|
||||
expect(wrapper.find(Filter)).to.have.lengthOf(2);
|
||||
wrapper.instance().removeFilter(1);
|
||||
expect(defaultProps.onChange).to.have.property('callCount', 2);
|
||||
expect(defaultProps.onChange.getCall(1).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: ['a', 'b', 'd'],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
before(() => {
|
||||
sinon.stub($, 'ajax');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
$.ajax.restore();
|
||||
});
|
||||
|
||||
it('makes a GET request to retrieve value choices', () => {
|
||||
wrapper.instance().fetchFilterValues(0, 'col1');
|
||||
expect($.ajax.getCall(0).args[0].type).to.deep.equal('GET');
|
||||
expect($.ajax.getCall(0).args[0].url).to.deep.equal('/superset/filter/qtable/1/col1/');
|
||||
});
|
||||
|
||||
it('changes filter values when one is removed', () => {
|
||||
wrapper.instance().changeFilter(0, 'val', ['a', 'b']);
|
||||
expect(defaultProps.onChange).to.have.property('callCount', 3);
|
||||
expect(defaultProps.onChange.getCall(2).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: ['a', 'b'],
|
||||
},
|
||||
{
|
||||
col: 'col2',
|
||||
op: '==',
|
||||
val: 'Z',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('changes filter values when one is added', () => {
|
||||
wrapper.instance().changeFilter(0, 'val', ['a', 'b', 'd', 'e']);
|
||||
expect(defaultProps.onChange).to.have.property('callCount', 4);
|
||||
expect(defaultProps.onChange.getCall(3).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: ['a', 'b', 'd', 'e'],
|
||||
},
|
||||
{
|
||||
col: 'col2',
|
||||
op: '==',
|
||||
val: 'Z',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('changes op and transforms values', () => {
|
||||
wrapper.instance().changeFilter(0, ['val', 'op'], ['a', '==']);
|
||||
wrapper.instance().changeFilter(1, ['val', 'op'], [['Z'], 'in']);
|
||||
expect(defaultProps.onChange).to.have.property('callCount', 6);
|
||||
expect(defaultProps.onChange.getCall(4).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col1',
|
||||
op: '==',
|
||||
val: 'a',
|
||||
},
|
||||
{
|
||||
col: 'col2',
|
||||
op: '==',
|
||||
val: 'Z',
|
||||
},
|
||||
]);
|
||||
expect(defaultProps.onChange.getCall(5).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: ['a', 'b', 'd'],
|
||||
},
|
||||
{
|
||||
col: 'col2',
|
||||
op: 'in',
|
||||
val: ['Z'],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('changes column and clears invalid values', () => {
|
||||
wrapper.instance().changeFilter(0, 'col', 'col2');
|
||||
expect(defaultProps.onChange).to.have.property('callCount', 7);
|
||||
expect(defaultProps.onChange.getCall(6).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col2',
|
||||
op: 'in',
|
||||
val: [],
|
||||
},
|
||||
{
|
||||
col: 'col2',
|
||||
op: '==',
|
||||
val: 'Z',
|
||||
},
|
||||
]);
|
||||
wrapper.instance().changeFilter(1, 'col', 'col1');
|
||||
expect(defaultProps.onChange).to.have.property('callCount', 8);
|
||||
expect(defaultProps.onChange.getCall(7).args[0]).to.deep.equal([
|
||||
{
|
||||
col: 'col1',
|
||||
op: 'in',
|
||||
val: ['a', 'b', 'd'],
|
||||
},
|
||||
{
|
||||
col: 'col1',
|
||||
op: '==',
|
||||
val: '',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('tracks an active filter select ajax request', () => {
|
||||
const spyReq = sinon.spy();
|
||||
$.ajax.reset();
|
||||
$.ajax.onFirstCall().returns(spyReq);
|
||||
wrapper.instance().fetchFilterValues(0, 'col1');
|
||||
expect(wrapper.state().activeRequest).to.equal(spyReq);
|
||||
// Sets active to null after success
|
||||
$.ajax.getCall(0).args[0].success(['opt1', 'opt2', null, '']);
|
||||
expect(wrapper.state().filters[0].valuesLoading).to.equal(false);
|
||||
expect(wrapper.state().filters[0].valueChoices).to.deep.equal(['opt1', 'opt2', null, '']);
|
||||
expect(wrapper.state().activeRequest).to.equal(null);
|
||||
});
|
||||
|
||||
|
||||
it('cancels active request if another is submitted', () => {
|
||||
const spyReq = sinon.spy();
|
||||
spyReq.abort = sinon.spy();
|
||||
$.ajax.reset();
|
||||
$.ajax.onFirstCall().returns(spyReq);
|
||||
wrapper.instance().fetchFilterValues(0, 'col1');
|
||||
expect(wrapper.state().activeRequest).to.equal(spyReq);
|
||||
const spyReq1 = sinon.spy();
|
||||
$.ajax.onSecondCall().returns(spyReq1);
|
||||
wrapper.instance().fetchFilterValues(1, 'col2');
|
||||
expect(spyReq.abort.called).to.equal(true);
|
||||
expect(wrapper.state().activeRequest).to.equal(spyReq1);
|
||||
});
|
||||
});
|
|
@ -1,115 +0,0 @@
|
|||
/* eslint-disable no-unused-expressions */
|
||||
import React from 'react';
|
||||
import Select from 'react-select';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import sinon from 'sinon';
|
||||
import { expect } from 'chai';
|
||||
import { describe, it, beforeEach } from 'mocha';
|
||||
import { shallow } from 'enzyme';
|
||||
import Filter from '../../../../src/explore/components/controls/Filter';
|
||||
import SelectControl from '../../../../src/explore/components/controls/SelectControl';
|
||||
|
||||
const defaultProps = {
|
||||
changeFilter: sinon.spy(),
|
||||
removeFilter: () => {},
|
||||
filter: {
|
||||
col: null,
|
||||
op: 'in',
|
||||
value: ['val'],
|
||||
},
|
||||
datasource: {
|
||||
id: 1,
|
||||
type: 'qtable',
|
||||
filter_select: false,
|
||||
filterable_cols: ['col1', 'col2'],
|
||||
metrics_combo: [
|
||||
['m1', 'v1'],
|
||||
['m2', 'v2'],
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
describe('Filter', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<Filter {...defaultProps} />);
|
||||
});
|
||||
|
||||
it('renders Filters', () => {
|
||||
expect(
|
||||
React.isValidElement(<Filter {...defaultProps} />),
|
||||
).to.equal(true);
|
||||
});
|
||||
|
||||
it('renders two selects, one button and one input', () => {
|
||||
expect(wrapper.find(Select)).to.have.lengthOf(2);
|
||||
expect(wrapper.find(Button)).to.have.lengthOf(1);
|
||||
expect(wrapper.find(SelectControl)).to.have.lengthOf(1);
|
||||
expect(wrapper.find('#select-op').prop('options')).to.have.lengthOf(10);
|
||||
});
|
||||
|
||||
it('renders five op choices for table datasource', () => {
|
||||
const props = Object.assign({}, defaultProps);
|
||||
props.datasource = {
|
||||
id: 1,
|
||||
type: 'druid',
|
||||
filter_select: false,
|
||||
filterable_cols: ['country_name'],
|
||||
};
|
||||
const druidWrapper = shallow(<Filter {...props} />);
|
||||
expect(druidWrapper.find('#select-op').prop('options')).to.have.lengthOf(11);
|
||||
});
|
||||
|
||||
it('renders six op choices for having filter', () => {
|
||||
const props = Object.assign({}, defaultProps);
|
||||
props.having = true;
|
||||
const havingWrapper = shallow(<Filter {...props} />);
|
||||
expect(havingWrapper.find('#select-op').prop('options')).to.have.lengthOf(6);
|
||||
});
|
||||
|
||||
it('calls changeFilter when select is changed', () => {
|
||||
const selectCol = wrapper.find('#select-col');
|
||||
selectCol.simulate('change', { value: 'col' });
|
||||
const selectOp = wrapper.find('#select-op');
|
||||
selectOp.simulate('change', { value: 'in' });
|
||||
const selectVal = wrapper.find(SelectControl);
|
||||
selectVal.simulate('change', { value: 'x' });
|
||||
expect(defaultProps.changeFilter).to.have.property('callCount', 3);
|
||||
});
|
||||
|
||||
it('renders input for regex filters', () => {
|
||||
const props = Object.assign({}, defaultProps);
|
||||
props.filter = {
|
||||
col: null,
|
||||
op: 'regex',
|
||||
value: 'val',
|
||||
};
|
||||
const regexWrapper = shallow(<Filter {...props} />);
|
||||
expect(regexWrapper.find('input')).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it('renders `input` for text filters', () => {
|
||||
const props = Object.assign({}, defaultProps);
|
||||
['>=', '>', '<=', '<'].forEach((op) => {
|
||||
props.filter = {
|
||||
col: 'col1',
|
||||
op,
|
||||
value: 'val',
|
||||
};
|
||||
wrapper = shallow(<Filter {...props} />);
|
||||
expect(wrapper.find('input')).to.have.lengthOf(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('replaces null filter values with empty string in `input`', () => {
|
||||
const props = Object.assign({}, defaultProps);
|
||||
props.filter = {
|
||||
col: 'col1',
|
||||
op: '>=',
|
||||
value: null,
|
||||
};
|
||||
wrapper = shallow(<Filter {...props} />);
|
||||
expect(wrapper.find('input').props().value).to.equal('');
|
||||
});
|
||||
});
|
|
@ -42,6 +42,10 @@ export default class AlteredSliceTag extends React.Component {
|
|||
if (!ofd[fdKey] && !cfd[fdKey]) {
|
||||
continue;
|
||||
}
|
||||
// Ignore obsolete legacy filters
|
||||
if (['filters', 'having', 'having_filters', 'where'].includes(fdKey)) {
|
||||
continue;
|
||||
}
|
||||
if (!isEqual(ofd[fdKey], cfd[fdKey])) {
|
||||
diffs[fdKey] = { before: ofd[fdKey], after: cfd[fdKey] };
|
||||
}
|
||||
|
@ -56,13 +60,15 @@ export default class AlteredSliceTag extends React.Component {
|
|||
return 'N/A';
|
||||
} else if (value === null) {
|
||||
return 'null';
|
||||
} else if (controls[key] && controls[key].type === 'FilterControl') {
|
||||
} else if (controls[key] && controls[key].type === 'AdhocFilterControl') {
|
||||
if (!value.length) {
|
||||
return '[]';
|
||||
}
|
||||
return value.map((v) => {
|
||||
const filterVal = v.val && v.val.constructor === Array ? `[${v.val.join(', ')}]` : v.val;
|
||||
return `${v.col} ${v.op} ${filterVal}`;
|
||||
const filterVal = v.comparator && v.comparator.constructor === Array ?
|
||||
`[${v.comparator.join(', ')}]` :
|
||||
v.comparator;
|
||||
return `${v.subject} ${v.operator} ${filterVal}`;
|
||||
}).join(', ');
|
||||
} else if (controls[key] && controls[key].type === 'BoundsControl') {
|
||||
return `Min: ${value[0]}, Max: ${value[1]}`;
|
||||
|
|
|
@ -16,12 +16,6 @@ import OnPasteSelect from '../../../components/OnPasteSelect';
|
|||
import AdhocFilterOption from '../AdhocFilterOption';
|
||||
import FilterDefinitionOption from '../FilterDefinitionOption';
|
||||
|
||||
const legacyFilterShape = PropTypes.shape({
|
||||
col: PropTypes.string,
|
||||
op: PropTypes.string,
|
||||
val: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
|
||||
});
|
||||
|
||||
const propTypes = {
|
||||
name: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
|
@ -30,12 +24,8 @@ const propTypes = {
|
|||
columns: PropTypes.arrayOf(columnType),
|
||||
savedMetrics: PropTypes.arrayOf(savedMetricType),
|
||||
formData: PropTypes.shape({
|
||||
filters: PropTypes.arrayOf(legacyFilterShape),
|
||||
having: PropTypes.string,
|
||||
having_filters: PropTypes.arrayOf(legacyFilterShape),
|
||||
metric: PropTypes.oneOfType([PropTypes.string, adhocMetricType]),
|
||||
metrics: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, adhocMetricType])),
|
||||
where: PropTypes.string,
|
||||
}),
|
||||
};
|
||||
|
||||
|
@ -55,13 +45,15 @@ export default class AdhocFilterControl extends React.Component {
|
|||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.coerceAdhocFilters = this.coerceAdhocFilters.bind(this);
|
||||
this.optionsForSelect = this.optionsForSelect.bind(this);
|
||||
this.onFilterEdit = this.onFilterEdit.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.getMetricExpression = this.getMetricExpression.bind(this);
|
||||
|
||||
const filters = this.coerceAdhocFilters(this.props.value, this.props.formData);
|
||||
const filters = (this.props.value || []).map(filter => (
|
||||
isDictionaryForAdhocFilter(filter) ? new AdhocFilter(filter) : filter
|
||||
));
|
||||
|
||||
this.optionRenderer = VirtualizedRendererWrap(option => (
|
||||
<FilterDefinitionOption option={option} />
|
||||
));
|
||||
|
@ -87,7 +79,11 @@ export default class AdhocFilterControl extends React.Component {
|
|||
this.setState({ options: this.optionsForSelect(nextProps) });
|
||||
}
|
||||
if (this.props.value !== nextProps.value) {
|
||||
this.setState({ values: this.coerceAdhocFilters(nextProps.value, nextProps.formData) });
|
||||
this.setState({
|
||||
values: (nextProps.value || []).map(
|
||||
filter => (isDictionaryForAdhocFilter(filter) ? new AdhocFilter(filter) : filter
|
||||
)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,62 +143,6 @@ export default class AdhocFilterControl extends React.Component {
|
|||
)).expression;
|
||||
}
|
||||
|
||||
coerceAdhocFilters(propsValues, formData) {
|
||||
// this converts filters from the four legacy filter controls into adhoc filters in the case
|
||||
// someone loads an old slice in the explore view
|
||||
if (propsValues) {
|
||||
return propsValues.map(filter => (
|
||||
isDictionaryForAdhocFilter(filter) ? new AdhocFilter(filter) : filter
|
||||
));
|
||||
}
|
||||
return [
|
||||
...(formData.filters || []).map(filter => (
|
||||
new AdhocFilter({
|
||||
subject: filter.col,
|
||||
operator: filter.op,
|
||||
comparator: filter.val,
|
||||
clause: CLAUSES.WHERE,
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
filterOptionName: this.generateConvertedFilterOptionName(),
|
||||
})
|
||||
)),
|
||||
...(formData.having_filters || []).map(filter => (
|
||||
new AdhocFilter({
|
||||
subject: filter.col,
|
||||
operator: filter.op,
|
||||
comparator: filter.val,
|
||||
clause: CLAUSES.HAVING,
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
filterOptionName: this.generateConvertedFilterOptionName(),
|
||||
})
|
||||
)),
|
||||
...[
|
||||
formData.where ?
|
||||
new AdhocFilter({
|
||||
sqlExpression: formData.where,
|
||||
clause: CLAUSES.WHERE,
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
filterOptionName: this.generateConvertedFilterOptionName(),
|
||||
}) :
|
||||
null,
|
||||
],
|
||||
...[
|
||||
formData.having ?
|
||||
new AdhocFilter({
|
||||
sqlExpression: formData.having,
|
||||
clause: CLAUSES.HAVING,
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
filterOptionName: this.generateConvertedFilterOptionName(),
|
||||
}) :
|
||||
null,
|
||||
],
|
||||
].filter(option => option);
|
||||
}
|
||||
|
||||
generateConvertedFilterOptionName() {
|
||||
return `form_filter_${Math.random().toString(36).substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`;
|
||||
}
|
||||
|
||||
optionsForSelect(props) {
|
||||
const options = [
|
||||
...props.columns,
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Select from 'react-select';
|
||||
import { Button, Row, Col } from 'react-bootstrap';
|
||||
import { t } from '../../../locales';
|
||||
import SelectControl from './SelectControl';
|
||||
|
||||
const operatorsArr = [
|
||||
{ val: 'in', type: 'array', useSelect: true, multi: true },
|
||||
{ val: 'not in', type: 'array', useSelect: true, multi: true },
|
||||
{ val: '==', type: 'string', useSelect: true, multi: false, havingOnly: true },
|
||||
{ val: '!=', type: 'string', useSelect: true, multi: false, havingOnly: true },
|
||||
{ val: '>=', type: 'string', havingOnly: true },
|
||||
{ val: '<=', type: 'string', havingOnly: true },
|
||||
{ val: '>', type: 'string', havingOnly: true },
|
||||
{ val: '<', type: 'string', havingOnly: true },
|
||||
{ val: 'regex', type: 'string', datasourceTypes: ['druid'] },
|
||||
{ val: 'LIKE', type: 'string', datasourceTypes: ['table'] },
|
||||
{ val: 'IS NULL', type: null },
|
||||
{ val: 'IS NOT NULL', type: null },
|
||||
];
|
||||
const operators = {};
|
||||
operatorsArr.forEach((op) => {
|
||||
operators[op.val] = op;
|
||||
});
|
||||
|
||||
const propTypes = {
|
||||
changeFilter: PropTypes.func,
|
||||
removeFilter: PropTypes.func,
|
||||
filter: PropTypes.object.isRequired,
|
||||
datasource: PropTypes.object,
|
||||
having: PropTypes.bool,
|
||||
valuesLoading: PropTypes.bool,
|
||||
valueChoices: PropTypes.array,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
changeFilter: () => {},
|
||||
removeFilter: () => {},
|
||||
datasource: null,
|
||||
having: false,
|
||||
valuesLoading: false,
|
||||
valueChoices: [],
|
||||
};
|
||||
|
||||
export default class Filter extends React.Component {
|
||||
|
||||
switchFilterValue(prevOp, nextOp) {
|
||||
if (operators[prevOp].type !== operators[nextOp].type) {
|
||||
// Switch from array to string or vice versa
|
||||
const val = this.props.filter.val;
|
||||
let newVal;
|
||||
if (operators[nextOp].type === 'string') {
|
||||
if (!val || !val.length) {
|
||||
newVal = '';
|
||||
} else {
|
||||
newVal = val[0];
|
||||
}
|
||||
} else if (operators[nextOp].type === 'array') {
|
||||
if (!val || !val.length) {
|
||||
newVal = [];
|
||||
} else {
|
||||
newVal = [val];
|
||||
}
|
||||
}
|
||||
this.props.changeFilter(['val', 'op'], [newVal, nextOp]);
|
||||
} else {
|
||||
// No value type change
|
||||
this.props.changeFilter('op', nextOp);
|
||||
}
|
||||
}
|
||||
|
||||
changeText(event) {
|
||||
this.props.changeFilter('val', event.target.value);
|
||||
}
|
||||
|
||||
changeSelect(value) {
|
||||
this.props.changeFilter('val', value);
|
||||
}
|
||||
|
||||
changeColumn(event) {
|
||||
this.props.changeFilter('col', event.value);
|
||||
}
|
||||
|
||||
changeOp(event) {
|
||||
this.switchFilterValue(this.props.filter.op, event.value);
|
||||
}
|
||||
|
||||
removeFilter(filter) {
|
||||
this.props.removeFilter(filter);
|
||||
}
|
||||
|
||||
renderFilterFormControl(filter) {
|
||||
const operator = operators[filter.op];
|
||||
if (operator.type === null) {
|
||||
// IS NULL or IS NOT NULL
|
||||
return null;
|
||||
}
|
||||
if (operator.useSelect && !this.props.having) {
|
||||
// TODO should use a simple Select, not a control here...
|
||||
return (
|
||||
<SelectControl
|
||||
multi={operator.multi}
|
||||
freeForm
|
||||
name="filter-value"
|
||||
value={filter.val}
|
||||
isLoading={this.props.valuesLoading}
|
||||
choices={this.props.valueChoices}
|
||||
onChange={this.changeSelect.bind(this)}
|
||||
showHeader={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<input
|
||||
type="text"
|
||||
onChange={this.changeText.bind(this)}
|
||||
value={filter.val || ''}
|
||||
className="form-control input-sm"
|
||||
placeholder={t('Filter value')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
const datasource = this.props.datasource;
|
||||
const filter = this.props.filter;
|
||||
const opsChoices = operatorsArr
|
||||
.filter((o) => {
|
||||
if (this.props.having) {
|
||||
return !!o.havingOnly;
|
||||
}
|
||||
return (!o.datasourceTypes || o.datasourceTypes.indexOf(datasource.type) >= 0);
|
||||
})
|
||||
.map(o => ({ value: o.val, label: o.val }));
|
||||
let colChoices;
|
||||
if (datasource) {
|
||||
if (this.props.having) {
|
||||
colChoices = datasource.metrics_combo.map(c => ({ value: c[0], label: c[1] }));
|
||||
} else {
|
||||
colChoices = datasource.filterable_cols.map(c => ({ value: c[0], label: c[1] }));
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Row className="space-1">
|
||||
<Col md={12}>
|
||||
<Select
|
||||
id="select-col"
|
||||
placeholder={this.props.having ? t('Select metric') : t('Select column')}
|
||||
clearable={false}
|
||||
options={colChoices}
|
||||
value={filter.col}
|
||||
onChange={this.changeColumn.bind(this)}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="space-1">
|
||||
<Col md={3}>
|
||||
<Select
|
||||
id="select-op"
|
||||
placeholder={t('Select operator')}
|
||||
options={opsChoices}
|
||||
clearable={false}
|
||||
value={filter.op}
|
||||
onChange={this.changeOp.bind(this)}
|
||||
/>
|
||||
</Col>
|
||||
<Col md={7}>
|
||||
{this.renderFilterFormControl(filter)}
|
||||
</Col>
|
||||
<Col md={2}>
|
||||
<Button
|
||||
id="remove-button"
|
||||
bsSize="small"
|
||||
onClick={this.removeFilter.bind(this)}
|
||||
>
|
||||
<i className="fa fa-minus" />
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Filter.propTypes = propTypes;
|
||||
Filter.defaultProps = defaultProps;
|
|
@ -1,155 +0,0 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button, Row, Col } from 'react-bootstrap';
|
||||
import Filter from './Filter';
|
||||
import { t } from '../../../locales';
|
||||
|
||||
const $ = window.$ = require('jquery');
|
||||
|
||||
const propTypes = {
|
||||
name: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
value: PropTypes.array,
|
||||
datasource: PropTypes.object,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
onChange: () => {},
|
||||
value: [],
|
||||
};
|
||||
|
||||
export default class FilterControl extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const initialFilters = props.value.map(() => ({
|
||||
valuesLoading: false,
|
||||
valueChoices: [],
|
||||
}));
|
||||
this.state = {
|
||||
filters: initialFilters,
|
||||
activeRequest: null,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.state.filters.forEach((filter, index) => this.fetchFilterValues(index));
|
||||
}
|
||||
|
||||
fetchFilterValues(index, column) {
|
||||
const datasource = this.props.datasource;
|
||||
const col = column || this.props.value[index].col;
|
||||
const having = this.props.name === 'having_filters';
|
||||
if (col && this.props.datasource && this.props.datasource.filter_select && !having) {
|
||||
this.setState((prevState) => {
|
||||
const newStateFilters = Object.assign([], prevState.filters);
|
||||
newStateFilters[index].valuesLoading = true;
|
||||
return { filters: newStateFilters };
|
||||
});
|
||||
// if there is an outstanding request to fetch values, cancel it.
|
||||
if (this.state.activeRequest) {
|
||||
this.state.activeRequest.abort();
|
||||
}
|
||||
this.setState({
|
||||
activeRequest: $.ajax({
|
||||
type: 'GET',
|
||||
url: `/superset/filter/${datasource.type}/${datasource.id}/${col}/`,
|
||||
success: (data) => {
|
||||
this.setState((prevState) => {
|
||||
const newStateFilters = Object.assign([], prevState.filters);
|
||||
newStateFilters[index] = { valuesLoading: false, valueChoices: data };
|
||||
return { filters: newStateFilters, activeRequest: null };
|
||||
});
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addFilter() {
|
||||
const newFilters = Object.assign([], this.props.value);
|
||||
const col = this.props.datasource && this.props.datasource.filterable_cols.length > 0 ?
|
||||
this.props.datasource.filterable_cols[0][0] :
|
||||
null;
|
||||
newFilters.push({
|
||||
col,
|
||||
op: 'in',
|
||||
val: this.props.datasource.filter_select ? [] : '',
|
||||
});
|
||||
this.props.onChange(newFilters);
|
||||
const nextIndex = this.state.filters.length;
|
||||
this.setState((prevState) => {
|
||||
const newStateFilters = Object.assign([], prevState.filters);
|
||||
newStateFilters.push({ valuesLoading: false, valueChoices: [] });
|
||||
return { filters: newStateFilters };
|
||||
});
|
||||
this.fetchFilterValues(nextIndex, col);
|
||||
}
|
||||
|
||||
changeFilter(index, control, value) {
|
||||
const newFilters = Object.assign([], this.props.value);
|
||||
const modifiedFilter = Object.assign({}, newFilters[index]);
|
||||
if (typeof control === 'string') {
|
||||
modifiedFilter[control] = value;
|
||||
} else {
|
||||
control.forEach((c, i) => {
|
||||
modifiedFilter[c] = value[i];
|
||||
});
|
||||
}
|
||||
// Clear selected values and refresh upon column change
|
||||
if (control === 'col') {
|
||||
if (modifiedFilter.val.constructor === Array) {
|
||||
modifiedFilter.val = [];
|
||||
} else if (typeof modifiedFilter.val === 'string') {
|
||||
modifiedFilter.val = '';
|
||||
}
|
||||
this.fetchFilterValues(index, value);
|
||||
}
|
||||
newFilters.splice(index, 1, modifiedFilter);
|
||||
this.props.onChange(newFilters);
|
||||
}
|
||||
|
||||
removeFilter(index) {
|
||||
this.props.onChange(this.props.value.filter((f, i) => i !== index));
|
||||
this.setState((prevState) => {
|
||||
const newStateFilters = Object.assign([], prevState.filters);
|
||||
newStateFilters.splice(index, 1);
|
||||
return { filters: newStateFilters };
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const filters = this.props.value.map((filter, i) => (
|
||||
<div key={i}>
|
||||
<Filter
|
||||
having={this.props.name === 'having_filters'}
|
||||
filter={filter}
|
||||
datasource={this.props.datasource}
|
||||
removeFilter={this.removeFilter.bind(this, i)}
|
||||
changeFilter={this.changeFilter.bind(this, i)}
|
||||
valuesLoading={this.state.filters[i].valuesLoading}
|
||||
valueChoices={this.state.filters[i].valueChoices}
|
||||
/>
|
||||
</div>
|
||||
));
|
||||
return (
|
||||
<div>
|
||||
{filters}
|
||||
<Row className="space-2">
|
||||
<Col md={2}>
|
||||
<Button
|
||||
id="add-button"
|
||||
bsSize="sm"
|
||||
onClick={this.addFilter.bind(this)}
|
||||
>
|
||||
<i className="fa fa-plus" /> {t('Add Filter')}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
FilterControl.propTypes = propTypes;
|
||||
FilterControl.defaultProps = defaultProps;
|
|
@ -6,7 +6,6 @@ import ColorPickerControl from './ColorPickerControl';
|
|||
import ColorSchemeControl from './ColorSchemeControl';
|
||||
import DatasourceControl from './DatasourceControl';
|
||||
import DateFilterControl from './DateFilterControl';
|
||||
import FilterControl from './FilterControl';
|
||||
import FixedOrMetricControl from './FixedOrMetricControl';
|
||||
import HiddenControl from './HiddenControl';
|
||||
import SelectAsyncControl from './SelectAsyncControl';
|
||||
|
@ -29,7 +28,6 @@ const controlMap = {
|
|||
ColorSchemeControl,
|
||||
DatasourceControl,
|
||||
DateFilterControl,
|
||||
FilterControl,
|
||||
FixedOrMetricControl,
|
||||
HiddenControl,
|
||||
SelectAsyncControl,
|
||||
|
|
|
@ -1132,34 +1132,6 @@ export const controls = {
|
|||
default: '',
|
||||
},
|
||||
|
||||
where: {
|
||||
type: 'TextAreaControl',
|
||||
label: t('Custom WHERE clause'),
|
||||
default: '',
|
||||
language: 'sql',
|
||||
minLines: 2,
|
||||
maxLines: 10,
|
||||
offerEditInModal: false,
|
||||
description: t('The text in this box gets included in your query\'s WHERE ' +
|
||||
'clause, as an AND to other criteria. You can include ' +
|
||||
'complex expression, parenthesis and anything else ' +
|
||||
'supported by the backend it is directed towards.'),
|
||||
},
|
||||
|
||||
having: {
|
||||
type: 'TextAreaControl',
|
||||
label: t('Custom HAVING clause'),
|
||||
default: '',
|
||||
language: 'sql',
|
||||
minLines: 2,
|
||||
maxLines: 10,
|
||||
offerEditInModal: false,
|
||||
description: t('The text in this box gets included in your query\'s HAVING ' +
|
||||
'clause, as an AND to other criteria. You can include ' +
|
||||
'complex expression, parenthesis and anything else ' +
|
||||
'supported by the backend it is directed towards.'),
|
||||
},
|
||||
|
||||
compare_lag: {
|
||||
type: 'TextControl',
|
||||
label: t('Comparison Period Lag'),
|
||||
|
@ -1822,16 +1794,6 @@ export const controls = {
|
|||
description: t('Labels for the marker lines'),
|
||||
},
|
||||
|
||||
filters: {
|
||||
type: 'FilterControl',
|
||||
label: '',
|
||||
default: [],
|
||||
description: '',
|
||||
mapStateToProps: state => ({
|
||||
datasource: state.datasource,
|
||||
}),
|
||||
},
|
||||
|
||||
annotation_layers: {
|
||||
type: 'AnnotationLayerControl',
|
||||
label: '',
|
||||
|
@ -1854,18 +1816,6 @@ export const controls = {
|
|||
provideFormDataToProps: true,
|
||||
},
|
||||
|
||||
having_filters: {
|
||||
type: 'FilterControl',
|
||||
label: '',
|
||||
default: [],
|
||||
description: '',
|
||||
mapStateToProps: state => ({
|
||||
choices: (state.datasource) ? state.datasource.metrics_combo
|
||||
.concat(state.datasource.filterable_cols) : [],
|
||||
datasource: state.datasource,
|
||||
}),
|
||||
},
|
||||
|
||||
slice_id: {
|
||||
type: 'HiddenControl',
|
||||
label: t('Chart ID'),
|
||||
|
|
|
@ -68,14 +68,6 @@ export function getControlsState(state, form_data) {
|
|||
delete formData[k];
|
||||
}
|
||||
}
|
||||
// Removing invalid filters that point to a now inexisting column
|
||||
if (control.type === 'FilterControl' && control.choices) {
|
||||
if (!formData[k]) {
|
||||
formData[k] = [];
|
||||
}
|
||||
const choiceValues = control.choices.map(c => c[0]);
|
||||
formData[k] = formData[k].filter(flt => choiceValues.indexOf(flt.col) >= 0);
|
||||
}
|
||||
|
||||
if (typeof control.default === 'function') {
|
||||
control.default = control.default(control);
|
||||
|
|
|
@ -40,14 +40,6 @@ export const sections = {
|
|||
['since', 'until'],
|
||||
],
|
||||
},
|
||||
sqlClause: {
|
||||
label: t('SQL'),
|
||||
controlSetRows: [
|
||||
['where'],
|
||||
['having'],
|
||||
],
|
||||
description: t('This section exposes ways to include snippets of SQL in your query'),
|
||||
},
|
||||
annotations: {
|
||||
label: t('Annotations and Layers'),
|
||||
expanded: true,
|
||||
|
@ -80,20 +72,6 @@ export const sections = {
|
|||
],
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
{
|
||||
label: t('Filters'),
|
||||
expanded: true,
|
||||
controlSetRows: [['filters']],
|
||||
},
|
||||
{
|
||||
label: t('Result Filters'),
|
||||
expanded: true,
|
||||
description: t('The filters to apply after post-aggregation.' +
|
||||
'Leave the value control empty to filter empty strings or nulls'),
|
||||
controlSetRows: [['having_filters']],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const timeGrainSqlaAnimationOverrides = {
|
||||
|
@ -263,6 +241,13 @@ export const visTypes = {
|
|||
['line_charts_2', 'y_axis_2_format'],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
sections.annotations,
|
||||
],
|
||||
controlOverrides: {
|
||||
|
@ -279,8 +264,6 @@ export const visTypes = {
|
|||
},
|
||||
},
|
||||
sectionOverrides: {
|
||||
sqlClause: [],
|
||||
filters: [[]],
|
||||
datasourceAndVizType: {
|
||||
label: t('Chart Type'),
|
||||
controlSetRows: [
|
||||
|
@ -310,7 +293,9 @@ export const visTypes = {
|
|||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['metric', 'freq'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['freq'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -373,6 +358,13 @@ export const visTypes = {
|
|||
['metric_2', 'y_axis_2_format'],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
sections.annotations,
|
||||
],
|
||||
controlOverrides: {
|
||||
|
@ -489,6 +481,13 @@ export const visTypes = {
|
|||
['deck_slices', null],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
@ -502,6 +501,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['spatial', 'size'],
|
||||
['row_limit', null],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -540,6 +540,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['spatial', 'size'],
|
||||
['row_limit', null],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -579,6 +580,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['line_column', 'line_type'],
|
||||
['row_limit', null],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -612,6 +614,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['spatial', 'size'],
|
||||
['row_limit', null],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -656,6 +659,7 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['geojson', 'row_limit'],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -696,6 +700,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['line_column', 'line_type'],
|
||||
['row_limit', null],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -736,6 +741,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['start_spatial', 'end_spatial'],
|
||||
['row_limit', null],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -784,6 +790,7 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['spatial', 'row_limit'],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -901,6 +908,13 @@ export const visTypes = {
|
|||
['row_limit', null],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Options'),
|
||||
expanded: true,
|
||||
|
@ -929,7 +943,9 @@ export const visTypes = {
|
|||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['groupby', 'metrics'],
|
||||
['metrics'],
|
||||
['adhoc_filters'],
|
||||
['groupby'],
|
||||
['limit'],
|
||||
['column_collection'],
|
||||
['url'],
|
||||
|
@ -969,8 +985,10 @@ export const visTypes = {
|
|||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['groupby', 'columns'],
|
||||
['metrics'],
|
||||
['adhoc_filters'],
|
||||
['groupby'],
|
||||
['columns'],
|
||||
['row_limit', null],
|
||||
],
|
||||
},
|
||||
|
@ -1017,7 +1035,9 @@ export const visTypes = {
|
|||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['series', 'metric'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['series'],
|
||||
['row_limit', null],
|
||||
],
|
||||
},
|
||||
|
@ -1040,6 +1060,7 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['metrics'],
|
||||
['adhoc_filters'],
|
||||
['groupby'],
|
||||
],
|
||||
},
|
||||
|
@ -1070,6 +1091,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['domain_granularity', 'subdomain_granularity'],
|
||||
['metrics'],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1106,7 +1128,9 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['metrics'],
|
||||
['groupby', 'limit'],
|
||||
['adhoc_filters'],
|
||||
['groupby'],
|
||||
['limit'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1128,8 +1152,11 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['series', 'entity'],
|
||||
['x', 'y'],
|
||||
['size', 'max_bubble_size'],
|
||||
['x'],
|
||||
['y'],
|
||||
['adhoc_filters'],
|
||||
['size'],
|
||||
['max_bubble_size'],
|
||||
['limit', null],
|
||||
],
|
||||
},
|
||||
|
@ -1179,6 +1206,7 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1256,6 +1284,7 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['all_columns_x'],
|
||||
['adhoc_filters'],
|
||||
['row_limit'],
|
||||
['groupby'],
|
||||
],
|
||||
|
@ -1298,7 +1327,9 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['groupby'],
|
||||
['metric', 'secondary_metric'],
|
||||
['metric'],
|
||||
['secondary_metric'],
|
||||
['adhoc_filters'],
|
||||
['row_limit'],
|
||||
],
|
||||
},
|
||||
|
@ -1338,6 +1369,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['groupby'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['row_limit'],
|
||||
],
|
||||
},
|
||||
|
@ -1366,6 +1398,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['groupby'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['row_limit'],
|
||||
],
|
||||
},
|
||||
|
@ -1391,8 +1424,11 @@ export const visTypes = {
|
|||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['groupby', 'columns'],
|
||||
['metric', 'row_limit'],
|
||||
['groupby'],
|
||||
['columns'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['row_limit'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1432,6 +1468,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['entity'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1467,6 +1504,7 @@ export const visTypes = {
|
|||
['entity'],
|
||||
['country_fieldtype'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1503,6 +1541,7 @@ export const visTypes = {
|
|||
controlSetRows: [
|
||||
['groupby'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['date_filter', 'instant_filtering'],
|
||||
['show_sqla_time_granularity', 'show_sqla_time_column'],
|
||||
['show_druid_time_granularity', 'show_druid_time_origin'],
|
||||
|
@ -1544,6 +1583,7 @@ export const visTypes = {
|
|||
['series'],
|
||||
['metrics'],
|
||||
['secondary_metric'],
|
||||
['adhoc_filters'],
|
||||
['limit'],
|
||||
],
|
||||
},
|
||||
|
@ -1564,7 +1604,9 @@ export const visTypes = {
|
|||
expanded: true,
|
||||
controlSetRows: [
|
||||
['all_columns_x', 'all_columns_y'],
|
||||
['metric', 'row_limit'],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['row_limit'],
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -1627,6 +1669,7 @@ export const visTypes = {
|
|||
['all_columns_x', 'all_columns_y'],
|
||||
['clustering_radius'],
|
||||
['row_limit'],
|
||||
['adhoc_filters'],
|
||||
['groupby'],
|
||||
],
|
||||
},
|
||||
|
@ -1701,6 +1744,13 @@ export const visTypes = {
|
|||
['min_leaf_node_event_count'],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['adhoc_filters'],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Additional meta data'),
|
||||
controlSetRows: [
|
||||
|
@ -1799,12 +1849,6 @@ export const visTypes = {
|
|||
|
||||
export default visTypes;
|
||||
|
||||
function adhocFilterEnabled(viz) {
|
||||
return viz.controlPanelSections.find((
|
||||
section => section.controlSetRows.find(row => row.find(control => control === 'adhoc_filters'))
|
||||
));
|
||||
}
|
||||
|
||||
export function sectionsToRender(vizType, datasourceType) {
|
||||
const viz = visTypes[vizType];
|
||||
|
||||
|
@ -1826,7 +1870,5 @@ export function sectionsToRender(vizType, datasourceType) {
|
|||
sectionsCopy.datasourceAndVizType,
|
||||
datasourceType === 'table' ? sectionsCopy.sqlaTimeSeries : sectionsCopy.druidTimeSeries,
|
||||
viz.controlPanelSections,
|
||||
!adhocFilterEnabled(viz) && (datasourceType === 'table' ? sectionsCopy.sqlClause : []),
|
||||
!adhocFilterEnabled(viz) && (datasourceType === 'table' ? sectionsCopy.filters[0] : sectionsCopy.filters),
|
||||
).filter(section => section);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
"""adhoc filters
|
||||
|
||||
Revision ID: bddc498dd179
|
||||
Revises: afb7730f6a9c
|
||||
Create Date: 2018-06-13 14:54:47.086507
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'bddc498dd179'
|
||||
down_revision = '80a67c5192fa'
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
import json
|
||||
import uuid
|
||||
|
||||
from alembic import op
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import Column, Integer, Text
|
||||
|
||||
from superset import db
|
||||
from superset import utils
|
||||
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class Slice(Base):
|
||||
__tablename__ = 'slices'
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
params = Column(Text)
|
||||
|
||||
|
||||
def upgrade():
|
||||
bind = op.get_bind()
|
||||
session = db.Session(bind=bind)
|
||||
mapping = {'having': 'having_filters', 'where': 'filters'}
|
||||
|
||||
for slc in session.query(Slice).all():
|
||||
try:
|
||||
params = json.loads(slc.params)
|
||||
|
||||
if not 'adhoc_filters' in params:
|
||||
params['adhoc_filters'] = []
|
||||
|
||||
for clause, filters in mapping.items():
|
||||
if clause in params and params[clause] != '':
|
||||
params['adhoc_filters'].append({
|
||||
'clause': clause.upper(),
|
||||
'expressionType': 'SQL',
|
||||
'filterOptionName': str(uuid.uuid4()),
|
||||
'sqlExpression': params[clause],
|
||||
})
|
||||
|
||||
if filters in params:
|
||||
for filt in params[filters]:
|
||||
params['adhoc_filters'].append({
|
||||
'clause': clause.upper(),
|
||||
'comparator': filt['val'],
|
||||
'expressionType': 'SIMPLE',
|
||||
'filterOptionName': str(uuid.uuid4()),
|
||||
'operator': filt['op'],
|
||||
'subject': filt['col'],
|
||||
})
|
||||
|
||||
for key in ('filters', 'having', 'having_filters', 'where'):
|
||||
if key in params:
|
||||
del params[key]
|
||||
|
||||
slc.params = json.dumps(params, sort_keys=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
session.commit()
|
||||
session.close()
|
||||
|
||||
|
||||
def downgrade():
|
||||
bind = op.get_bind()
|
||||
session = db.Session(bind=bind)
|
||||
|
||||
for slc in session.query(Slice).all():
|
||||
try:
|
||||
params = json.loads(slc.params)
|
||||
utils.split_adhoc_filters_into_base_filters(params)
|
||||
|
||||
if 'adhoc_filters' in params:
|
||||
del params['adhoc_filters']
|
||||
|
||||
slc.params = json.dumps(params, sort_keys=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
session.commit()
|
||||
session.close()
|
|
@ -1193,7 +1193,6 @@ msgstr ""
|
|||
msgid "Select operator"
|
||||
msgstr ""
|
||||
|
||||
#: superset/assets/javascripts/explore/components/controls/FilterControl.jsx:138
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr ""
|
||||
|
|
|
@ -3815,7 +3815,6 @@ msgstr ""
|
|||
msgid "Select operator"
|
||||
msgstr ""
|
||||
|
||||
#: superset/assets/src/explore/components/controls/FilterControl.jsx:145
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr ""
|
||||
|
|
|
@ -1250,7 +1250,6 @@ msgstr "Selecciona la columna"
|
|||
msgid "Select operator"
|
||||
msgstr "Selecciona el operador"
|
||||
|
||||
#: superset/assets/javascripts/explore/components/controls/FilterControl.jsx:138
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr "Añadir Filtro"
|
||||
|
|
|
@ -3819,7 +3819,6 @@ msgstr ""
|
|||
msgid "Select operator"
|
||||
msgstr ""
|
||||
|
||||
#: superset/assets/src/explore/components/controls/FilterControl.jsx:145
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr "Ajouter un filtre"
|
||||
|
|
|
@ -1598,7 +1598,6 @@ msgstr "Seleziona una colonna"
|
|||
msgid "Select operator"
|
||||
msgstr "Seleziona operatore"
|
||||
|
||||
#: superset/assets/javascripts/explore/components/controls/FilterControl.jsx:145
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr "Aggiungi filtro"
|
||||
|
|
|
@ -1202,7 +1202,6 @@ msgstr "列を選択"
|
|||
msgid "Select operator"
|
||||
msgstr "オペレータを選択"
|
||||
|
||||
#: superset/assets/javascripts/explore/components/controls/FilterControl.jsx:138
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr "フィルターを追加"
|
||||
|
|
|
@ -3814,7 +3814,6 @@ msgstr ""
|
|||
msgid "Select operator"
|
||||
msgstr ""
|
||||
|
||||
#: superset/assets/src/explore/components/controls/FilterControl.jsx:145
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr ""
|
||||
|
|
|
@ -1256,7 +1256,6 @@ msgstr "Selecione a coluna"
|
|||
msgid "Select operator"
|
||||
msgstr "Selecione o operador"
|
||||
|
||||
#: superset/assets/javascripts/explore/components/controls/FilterControl.jsx:138
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr "Adicionar filtro"
|
||||
|
|
|
@ -1599,7 +1599,6 @@ msgstr "Выбрать столбец"
|
|||
msgid "Select operator"
|
||||
msgstr "Выбрать оператор"
|
||||
|
||||
#: superset/assets/javascripts/explore/components/controls/FilterControl.jsx:145
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr "Добавить фильтр"
|
||||
|
|
|
@ -3820,7 +3820,6 @@ msgstr "选择列"
|
|||
msgid "Select operator"
|
||||
msgstr "选择运算符"
|
||||
|
||||
#: superset/assets/src/explore/components/controls/FilterControl.jsx:145
|
||||
#: superset/templates/appbuilder/general/widgets/search.html:6
|
||||
msgid "Add Filter"
|
||||
msgstr "增加过滤条件"
|
||||
|
|
|
@ -881,4 +881,3 @@ def split_adhoc_filters_into_base_filters(fd):
|
|||
fd['having'] = ' AND '.join(['({})'.format(sql) for sql in sql_having_filters])
|
||||
fd['having_filters'] = simple_having_filters
|
||||
fd['filters'] = simple_where_filters
|
||||
del fd['adhoc_filters']
|
||||
|
|
Loading…
Reference in New Issue