Compare commits

...

2 Commits

Author SHA1 Message Date
Matan Borenkraout
708e6dfa73 chore: publish v0.17.7 2021-02-08 20:56:05 +02:00
Matan Borenkraout
fc02f0c7fc chore: start monorepo migration 2021-02-08 20:47:05 +02:00
2293 changed files with 547567 additions and 55008 deletions

View File

@@ -1,30 +1,7 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
**/*{.,-}min.js
**/*.sh
coverage/**
dist/*
images/*
node_modules/*
node_modules*/*
stylesheets/*
vendor/*
docs/*
src/dashboard/deprecated/*
src/temp/*
**/node_modules
*.d.ts
coverage/
node_modules/
public/
esm/
lib/
tmp/
dist/

View File

@@ -17,12 +17,7 @@
* under the License.
*/
module.exports = {
extends: [
'airbnb',
'prettier',
'prettier/react',
'plugin:react-hooks/recommended',
],
extends: ['airbnb', 'prettier', 'prettier/react', 'plugin:react-hooks/recommended'],
parser: 'babel-eslint',
parserOptions: {
ecmaFeatures: {
@@ -33,155 +28,17 @@ module.exports = {
browser: true,
},
settings: {
'import/resolver': 'webpack',
'import/resolver': {
webpack: {},
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
react: {
version: 'detect',
},
},
plugins: ['prettier', 'react'],
overrides: [
{
files: ['cypress-base/**/*'],
rules: {
'import/no-unresolved': 0,
'global-require': 0,
},
},
{
files: ['webpack*.js'],
env: {
node: true,
},
settings: {
'import/resolver': {
node: {},
},
},
},
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
extends: [
'airbnb',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/@typescript-eslint',
'prettier/react',
],
plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'react'],
rules: {
'@typescript-eslint/ban-ts-ignore': 0,
'@typescript-eslint/ban-ts-comment': 0, // disabled temporarily
'@typescript-eslint/ban-types': 0, // disabled temporarily
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-use-before-define': 1, // disabled temporarily
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
camelcase: 0,
'class-methods-use-this': 0,
curly: 1,
'func-names': 0,
'guard-for-in': 0,
'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
'import/extensions': [
'error',
{
'.ts': 'always',
'.tsx': 'always',
'.json': 'always',
},
],
'import/no-named-as-default-member': 0,
'import/prefer-default-export': 0,
indent: 0,
'jsx-a11y/anchor-is-valid': 1,
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
'new-cap': 0,
'no-bitwise': 0,
'no-continue': 0,
'no-mixed-operators': 0,
'no-multi-assign': 0,
'no-multi-spaces': 0,
'no-prototype-builtins': 0,
'no-restricted-properties': 0,
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'antd',
message:
'Please import Ant components from the index of common/components',
},
],
},
],
'no-shadow': 0, // re-enable up for discussion
'no-use-before-define': 0, // disabled temporarily
'padded-blocks': 0,
'prefer-arrow-callback': 0,
'prefer-destructuring': ['error', { object: true, array: false }],
'react/destructuring-assignment': 0, // re-enable up for discussion
'react/forbid-prop-types': 0,
'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
'react/jsx-fragments': 1,
'react/jsx-no-bind': 0,
'react/jsx-props-no-spreading': 0, // re-enable up for discussion
'react/no-array-index-key': 0,
'react/no-string-refs': 0,
'react/no-unescaped-entities': 0,
'react/no-unused-prop-types': 0,
'react/prop-types': 0,
'react/require-default-props': 0,
'react/sort-comp': 0, // TODO: re-enable in separate PR
'react/static-property-placement': 0, // re-enable up for discussion
'prettier/prettier': 'error',
},
settings: {
'import/resolver': {
webpack: {},
typescript: {},
},
react: {
version: 'detect',
},
},
},
{
files: ['*.stories.jsx', '*.stories.tsx'],
rules: {
// this is to keep eslint from complaining about storybook addons,
// since they are included as dev dependencies rather than direct dependencies.
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true },
],
},
},
{
files: [
'src/**/*.test.ts',
'src/**/*.test.tsx',
'src/**/*.test.js',
'src/**/*.test.jsx',
],
plugins: ['jest', 'jest-dom', 'no-only-tests'],
env: {
'jest/globals': true,
},
extends: ['plugin:jest/recommended', 'plugin:testing-library/react'],
rules: {
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true },
],
'jest/consistent-test-it': 'error',
'no-only-tests/no-only-tests': 'error',
},
},
],
rules: {
camelcase: [
'error',
@@ -190,8 +47,8 @@ module.exports = {
properties: 'never',
},
],
curly: 2,
'class-methods-use-this': 0,
curly: 1,
'func-names': 0,
'guard-for-in': 0,
'import/extensions': [
@@ -207,7 +64,7 @@ module.exports = {
'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
'import/prefer-default-export': 0,
indent: 0,
'jsx-a11y/anchor-is-valid': 1,
'jsx-a11y/anchor-is-valid': 0, // disabled temporarily
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
'new-cap': 0,
@@ -224,8 +81,7 @@ module.exports = {
paths: [
{
name: 'antd',
message:
'Please import Ant components from the index of common/components',
message: 'Please import Ant components from the index of common/components',
},
],
},
@@ -247,8 +103,145 @@ module.exports = {
'react/no-unused-prop-types': 0,
'react/prop-types': 0,
'react/require-default-props': 0,
'react/sort-comp': 0, // TODO: re-enable in separate PR
'react/static-property-placement': 0, // disabled temporarily
'prettier/prettier': 'error',
},
overrides: [
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
extends: [
'airbnb',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/@typescript-eslint',
'prettier/react',
],
plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'react'],
rules: {
'@typescript-eslint/ban-ts-ignore': 0,
'@typescript-eslint/ban-ts-comment': 0, // disabled temporarily
'@typescript-eslint/ban-types': 0, // disabled temporarily
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-use-before-define': 1,
'@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
camelcase: 0,
'class-methods-use-this': 0,
'func-names': 0,
'guard-for-in': 0,
// there is a bug related to re-exports with this rule
// which doesn't seem to have been fixed: https://github.com/benmosher/eslint-plugin-import/issues/1460
'import/named': 0,
'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
'import/extensions': [
'error',
{
'.ts': 'always',
'.tsx': 'always',
'.json': 'always',
},
],
'import/no-named-as-default-member': 0,
'import/prefer-default-export': 0,
indent: 0,
'jsx-a11y/anchor-is-valid': 0, // disabled temporarily
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
'new-cap': 0,
'no-bitwise': 0,
'no-continue': 0,
'no-mixed-operators': 0,
'no-multi-assign': 0,
'no-multi-spaces': 0,
'no-prototype-builtins': 0,
'no-restricted-properties': 0,
'no-shadow': 0, // re-enable up for discussion
'no-use-before-define': 0, // disabled temporarily
'padded-blocks': 0,
'prefer-arrow-callback': 0,
'prefer-destructuring': ['error', { object: true, array: false }],
'react/destructuring-assignment': 0, // re-enable up for discussion
'react/forbid-prop-types': 0,
'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
'react/jsx-fragments': 1,
'react/jsx-no-bind': 0,
'react/jsx-props-no-spreading': 0, // re-enable up for discussion
'react/no-array-index-key': 0,
'react/no-string-refs': 0,
'react/no-unescaped-entities': 0,
'react/no-unused-prop-types': 0,
'react/prop-types': 0,
'react/require-default-props': 0,
'react/static-property-placement': 0, // re-enable up for discussion
'prettier/prettier': 'error',
},
settings: {
'import/resolver': {
webpack: {},
typescript: {},
},
react: {
version: 'detect',
},
},
},
{
files: ['*.stories.jsx', '*.stories.tsx'],
rules: {
// this is to keep eslint from complaining about storybook addons,
// since they are included as dev dependencies rather than direct dependencies.
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
},
},
{
files: ['*.d.ts'],
rules: {
'max-classes-per-file': 0,
},
},
{
files: ['*.test.*', './**/test/**/*'],
plugins: ['jest', 'jest-dom', 'no-only-tests', 'testing-library'],
env: {
'jest/globals': true,
},
extends: ['plugin:jest/recommended', 'plugin:testing-library/react'],
rules: {
'import/no-extraneous-dependencies': 0,
'jest/consistent-test-it': 'error',
'jest/no-try-expect': 0,
'max-classes-per-file': 0,
'no-only-tests/no-only-tests': 'error',
'prefer-promise-reject-errors': 0,
},
},
{
files: ['webpack*.js', '.*rc.js', '*.config.js'],
env: {
node: true,
},
settings: {
'import/resolver': {
node: {},
},
},
},
{
files: './packages/generator-superset/**/*.test.*',
env: {
node: true,
},
settings: {
'import/resolver': {
node: {},
},
},
rules: {
'jest/expect-expect': 0,
},
},
],
};

View File

@@ -0,0 +1,5 @@
{
"paths": ["{packages,plugins}/*/{src,test,types}/**/*.{ts,tsx,js,jsx}"],
"ignores": ["**/node_modules/**/*"],
"port": 5004
}

View File

@@ -1,4 +1,45 @@
coverage/*
cypress/screenshots
cypress/videos
src/temp
.DS_Store
*.DS_Store
# Logs
logs/
*.log
# Cache
.bundle/
.happo/
.idea/
.next/
.cache
.eslintcache
.idea
*.iml
.npm
.vscode
.yarnclean
# Directories
build/
coverage/
dist/
esm/
lib/
public/
node_modules/
tmp/
_gh-pages/
# Custom
*.map
*.min.js
test-changelog.md
*.tsbuildinfo
# Ignore npm lock files, always use yarn.lock instead
npm-shrinkwrap.json
package-lock.json
# Ignore yarn.lock in packages
plugins/*/yarn.lock
packages/*/yarn.lock

2
superset-frontend/.npmrc Normal file
View File

@@ -0,0 +1,2 @@
package-lock=false
registry=http://localhost:4873

View File

@@ -0,0 +1,17 @@
_gh-pages/
coverage/
node_modules/
public/
esm/
lib/
tmp/
dist/
lerna.json
npm-shrinkwrap.json
package-lock.json
tsconfig.json
tsconfig.options.json
tsconfig.eslint.json
CHANGELOG.md
*.geojson
*-topo.json

View File

@@ -0,0 +1,13 @@
{
"arrowParens": "avoid",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"printWidth": 100,
"proseWrap": "always",
"requirePragma": false,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"useTabs": false
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
## Contributing guidelines
### Setup local development
1. clone this repo
2. have `yarn` install package dependencies and manage the symlinking between packages for you
```sh
git clone ...superset-ui && cd superset-ui
yarn install
yarn build
```
To build only selected packages or plugins,
```bash
yarn build "*chart-table"
```
### File organization
[lerna](https://github.com/lerna/lerna/) and [yarn](https://yarnpkg.com) are used to manage versions
and dependencies between packages in this monorepo.
```
superset-ui/
lerna.json
package.json
...
packages/
package1/
package.json
...
src/
test/ # unit tests
types/ # typescript type declarations
...
lib/ # commonjs output
esm/ # es module output
...
...
```
### Builds, linting, and testing
Each package defines its own build config, linting, and testing. You can have lerna run commands
across all packages using the syntax `yarn run test` (or `yarn run test:watch` for watch mode) from
the root `@superset-ui` directory.
- [Using Storybook](docs/storybook.md) - You can test your components independently from Superset
app.
- [Debugging Superset plugins in Superset app](docs/debugging.md) - Sometimes something went wrong
and you have to do it.
### Committing
This repository follows
[conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.3/) guideline for commit
messages and has a `commitlint` hook which will require you to have the valid commit message before
committing. You can use `npm run commit` to help you create a commit message.
### Publishing
**Prerequisite:** You'll need an [npmjs.com](https://npmjs.com) account that is part of the
`superset-ui` organization.
1. Make sure you're logged in to NPM from your shell. Run `npm login` if necessary.
2. To make the release, run `yarn run release` and follow the prompts.

201
superset-frontend/LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,80 @@
# @superset-ui
[![Codecov branch](https://img.shields.io/codecov/c/github/apache-superset/superset-ui/master.svg?style=flat-square)](https://codecov.io/gh/apache-superset/superset-ui/branch/master)
[![Build Status](https://img.shields.io/travis/com/apache-superset/superset-ui/master.svg?style=flat-square)](https://travis-ci.com/apache-superset/superset-ui)
[![David](https://img.shields.io/david/dev/apache-superset/superset-ui.svg?style=flat-square)](https://david-dm.org/apache-superset/superset-ui?type=dev)
Collection of packages that power the
[Apache Superset](https://github.com/apache/incubator-superset) UI, and can be used to craft custom
data applications that leverage a Superset backend :chart_with_upwards_trend:
## Demo
Most recent release: https://apache-superset.github.io/superset-ui/
Current master: https://superset-ui.now.sh/
## Packages
### Core packages
| Package | Version |
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [@superset-ui/core](https://github.com/apache-superset/superset-ui/tree/master/packages/superset-ui-core) | [![Version](https://img.shields.io/npm/v/@superset-ui/core.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/core) |
| [@superset-ui/chart-controls](https://github.com/apache-superset/superset-ui/tree/master/packages/superset-ui-chart-controls) | [![Version](https://img.shields.io/npm/v/@superset-ui/core.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/chart-controls) |
| [@superset-ui/generator-superset](https://github.com/apache-superset/superset-ui/tree/master/packages/generator-superset) | [![Version](https://img.shields.io/npm/v/@superset-ui/generator-superset.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/generator-superset) |
### Chart plugin packages
`@superset-ui/legacy-*` packages are extracted from the classic
[Apache Superset](https://github.com/apache/incubator-superset) and converted into plugins. These
packages are extracted with minimal changes (almost as-is). They also depend on legacy API
(`viz.py`) to function.
| Package | Version |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [@superset-ui/legacy-preset-chart-big-number](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-preset-chart-big-number) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-preset-chart-big-number.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-preset-chart-big-number) |
| [@superset-ui/legacy-preset-chart-nvd3](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-preset-chart-nvd3) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-preset-chart-nvd3.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-preset-chart-nvd3) |
| [@superset-ui/legacy-plugin-chart-calendar](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-calendar) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-calendar.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-calendar) |
| [@superset-ui/legacy-plugin-chart-chord](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-chord) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-chord.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-chord) |
| [@superset-ui/legacy-plugin-chart-country-map](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-country-map) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-country-map.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-country-map) |
| [@superset-ui/legacy-plugin-chart-event-flow](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-event-flow) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-event-flow.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-event-flow) |
| [@superset-ui/legacy-plugin-chart-force-directed](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-force-directed) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-force-directed.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-force-directed) |
| [@superset-ui/legacy-plugin-chart-heatmap](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-heatmap) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-heatmap.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-heatmap) |
| [@superset-ui/legacy-plugin-chart-histogram](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-histogram) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-histogram.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-histogram) |
| [@superset-ui/legacy-plugin-chart-horizon](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-horizon) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-horizon.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-horizon) |
| [@superset-ui/legacy-plugin-chart-iframe](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-iframe) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-iframe.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-iframe) |
| [@superset-ui/legacy-plugin-chart-markup](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-markup) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-markup.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-markup) |
| [@superset-ui/legacy-plugin-chart-map-box](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-map-box) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-map-box.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-map-box) |
| [@superset-ui/legacy-plugin-chart-paired-t-test](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-paired-t-test) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-paired-t-test.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-paired-t-test) |
| [@superset-ui/legacy-plugin-chart-parallel-coordinates](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-parallel-coordinates) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-parallel-coordinates.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-parallel-coordinates) |
| [@superset-ui/legacy-plugin-chart-partition](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-partition) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-partition.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-partition) |
| [@superset-ui/legacy-plugin-chart-pivot-table](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-pivot-table) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-pivot-table.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-pivot-table) |
| [@superset-ui/legacy-plugin-chart-rose](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-rose) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-rose.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-rose) |
| [@superset-ui/legacy-plugin-chart-sankey](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-sankey) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-sankey.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-sankey) |
| [@superset-ui/legacy-plugin-chart-sankey-loop](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-sankey-loop) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-sankey-loop.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-sankey-loop) |
| [@superset-ui/legacy-plugin-chart-sunburst](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-sunburst) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-sunburst.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-sunburst) |
| [@superset-ui/legacy-plugin-chart-treemap](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-treemap) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-treemap.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-treemap) |
| [@superset-ui/legacy-plugin-chart-world-map](https://github.com/apache-superset/superset-ui/tree/master/plugins/legacy-plugin-chart-world-map) | [![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-world-map.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-plugin-chart-world-map) |
`@superset-ui/plugin-*` packages are newer and higher quality in general. A key difference that they
do not depend on `viz.py` (which contain visualization-specific python code) and interface with
`/api/v1/query/`, a new generic endpoint instead meant to serve all visualizations, instead. Also
should be written in Typescript.
| Package | Version | Note |
| ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| [@superset-ui/plugin-chart-word-cloud](https://github.com/apache-superset/superset-ui/tree/master/plugins/plugin-chart-word-cloud) | [![Version](https://img.shields.io/npm/v/@superset-ui/plugin-chart-word-cloud.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/plugin-chart-word-cloud) | |
| [@superset-ui/plugin-chart-table](https://github.com/apache-superset/superset-ui/tree/master/plugins/plugin-chart-table) | [![Version](https://img.shields.io/npm/v/@superset-ui/plugin-chart-table.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/plugin-chart-table) | |
| [@superset-ui/preset-chart-xy](https://github.com/apache-superset/superset-ui/tree/master/plugins/preset-chart-xy) | [![Version](https://img.shields.io/npm/v/@superset-ui/preset-chart-xy.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/preset-chart-xy) | |
| [@superset-ui/plugin-chart-echarts](https://github.com/apache-superset/superset-ui/tree/master/plugins/plugin-chart-echarts) | [![Version](https://img.shields.io/npm/v/@superset-ui/plugin-chart-echarts.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/plugin-chart-echarts) | |
| [@superset-ui/plugin-filter-antd](https://github.com/apache-superset/superset-ui/tree/master/plugins/plugin-filter-antd) | [![Version](https://img.shields.io/npm/v/@superset-ui/plugin-chart-echarts.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/plugin-filter-antd) | |
## Contribution and development guide
Please read the [contributing guidelines](CONTRIBUTING.md) which include development environment
setup and other things you should know about coding in this repo.
### License
Apache-2.0

View File

@@ -1,84 +1,23 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const packageConfig = require('./package.json');
const { getConfig } = require('@airbnb/config-babel');
module.exports = {
sourceMaps: true,
sourceType: 'module',
retainLines: true,
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
loose: true,
modules: false,
shippedProposals: true,
targets: packageConfig.browserslist,
},
],
[
'@babel/preset-react',
{ development: process.env.BABEL_ENV === 'development' },
],
],
plugins: [
'lodash',
'@babel/plugin-syntax-dynamic-import',
['@babel/plugin-proposal-class-properties', { loose: true }],
['@babel/plugin-proposal-optional-chaining', { loose: true }],
['@babel/plugin-proposal-private-methods', { loose: true }],
['@babel/plugin-transform-runtime', { corejs: 3 }],
'react-hot-loader/babel',
],
const config = getConfig({
library: true,
react: true,
next: true,
esm: process.env.BABEL_OUTPUT === 'esm',
node: process.env.NODE_ENV === 'test',
typescript: true,
env: {
// Setup a different config for tests as they run in node instead of a browser
test: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
loose: true,
shippedProposals: true,
modules: 'commonjs',
targets: { node: 'current' },
},
],
],
plugins: ['babel-plugin-dynamic-import-node'],
},
// build instrumented code for testing code coverage with Cypress
instrumented: {
plugins: ['istanbul'],
},
production: {
plugins: [
[
'babel-plugin-jsx-remove-data-test-id',
{
attributes: 'data-test',
},
],
],
},
targets: false,
},
};
});
// Override to allow transpile es modules inside vega-lite
config.ignore = config.ignore.filter(item => item !== 'node_modules/');
config.ignore.push('node_modules/(?!(vega-lite|lodash-es))');
config.plugins = [
['babel-plugin-transform-dev', { evaluate: false }],
['babel-plugin-typescript-to-proptypes', { loose: true }],
['@babel/plugin-proposal-class-properties', { loose: true }],
];
module.exports = config;

View File

@@ -0,0 +1,22 @@
coverage:
status:
patch: off
project:
default:
target: 0%
threshold: 10%
core-packages-ts:
target: 100%
paths:
- 'packages'
- '!packages/**/*.jsx'
- '!packages/**/*.tsx'
core-packages-tsx:
target: 50%
paths:
- 'packages/**/*.jsx'
- 'packages/**/*.tsx'
plugins:
target: 0
paths:
- plugins

View File

@@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional', '@commitlint/config-lerna-scopes'],
};

View File

@@ -0,0 +1,27 @@
# Debug Superset plugins in Superset app
## Activate plugins for local development
1. First, make sure you have run `yarn` and `yarn build` in `superset-ui` or your own plugin repo.
2. Go to
[superset-frontend](https://github.com/apache/incubator-superset/tree/master/superset-frontend),
use `npm link` to create a symlink of the plugin source code in `node_modules`:
```sh
cd incubator-superset/superset-frontend
# npm link ~/path/to/your/plugin
npm link ../../superset-ui/plugins/plugin-chart-word-cloud
```
3. Start developing with webpack dev server:
```sh
npm run dev-server
```
The dev server will automatically build from the source code under `path/to/your-plugin/src` and
watch the changes.
## Deactivate plugins
To deactivate a plugin, simply run `npm install` in `incubator-superset/superset-frontend` again.

View File

@@ -0,0 +1,13 @@
## Using Storybook
You can demo your changes by running the storybook demo locally with the following commands:
```sh
yarn install
yarn build
yarn storybook
```
The Storybook will
[automatically build from the source code](https://github.com/apache-superset/superset-ui/blob/master/packages/superset-ui-demo/.storybook/main.js#L49-L58)
when package names start with `@superset-ui/`.

View File

@@ -1,46 +1,61 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
module.exports = {
testRegex: '(\\/spec|\\/src)\\/.*(_spec|\\.test)\\.(j|t)sx?$',
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/spec/__mocks__/styleMock.js',
'\\.(gif|ttf|eot)$': '<rootDir>/spec/__mocks__/fileMock.js',
'\\.svg$': '<rootDir>/spec/__mocks__/svgrMock.js',
'^src/(.*)$': '<rootDir>/src/$1',
'^spec/(.*)$': '<rootDir>/spec/$1',
},
testEnvironment: 'enzyme',
setupFilesAfterEnv: ['<rootDir>/spec/helpers/setup.ts'],
testURL: 'http://localhost',
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
coverageDirectory: '<rootDir>/coverage/',
transform: {
'^.+\\.jsx?$': 'babel-jest',
'^.+\\.tsx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
globals: {
'ts-jest': {
babelConfig: true,
diagnostics: {
warnOnly: true,
},
bail: false,
collectCoverageFrom: ['**/src/**/*.{ts,tsx,js,jsx}', '**/test/**/*.{ts,tsx,js,jsx}'],
coverageDirectory: './coverage',
coveragePathIgnorePatterns: [
'coverage/',
'node_modules/',
'public/',
'esm/',
'lib/',
'tmp/',
'dist/',
],
coverageReporters: ['lcov', 'json-summary', 'html'],
coverageThreshold: {
global: {
branches: 0,
functions: 0,
lines: 0,
statements: 0,
},
},
globals: {
__DEV__: true,
caches: true,
},
moduleFileExtensions: ['mock.js', 'ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: {
'^.+\\.(ttf|eot|otf|svg|woff|woff2|mp3|png|jpg|jpeg|gif|ico)$':
'<rootDir>/node_modules/@airbnb/config-jest/mocks/file.js',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
'\\.(css|less)$': 'identity-obj-proxy',
},
roots: ['<rootDir>/packages', '<rootDir>/plugins'],
setupFiles: [
'<rootDir>/node_modules/@airbnb/config-jest/setup/shims.js',
'<rootDir>/node_modules/@airbnb/config-jest/setup/console.js',
'<rootDir>/node_modules/@airbnb/config-jest/setup/dom.js',
],
setupFilesAfterEnv: [
'<rootDir>/node_modules/@airbnb/config-jest/bootstrap/react.js',
'<rootDir>/node_modules/@airbnb/config-jest/bootstrap/consumer.js',
'@airbnb/config-jest/enzyme',
],
testEnvironment: 'jsdom',
testURL: 'http://localhost',
timers: 'real',
verbose: false,
transformIgnorePatterns: ['node_modules/(?!(vega-lite|lodash-es))'],
testPathIgnorePatterns: ['packages/generator-superset/generators'],
projects: [
'<rootDir>',
{
displayName: 'node',
rootDir: '<rootDir>/packages/generator-superset',
testMatch: ['<rootDir>/test/**/?(*.)+(spec|test).{js,jsx,ts,tsx}'],
testEnvironment: 'node',
},
],
};

View File

@@ -0,0 +1,26 @@
{
"lerna": "3.2.1",
"npmClient": "yarn",
"packages": [
"packages/*",
"plugins/*"
],
"useWorkspaces": true,
"version": "0.17.7",
"ignoreChanges": [
"**/*.md",
"**/*.spec.tsx?",
"**/*.spec.jsx?",
"**/__mocks__/**"
],
"command": {
"publish": {
"message": "chore: publish %s",
"graphType": "all"
},
"version": {
"message": "chore: publish %s",
"exact": true
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,250 +1,92 @@
{
"name": "superset",
"version": "0.999.0dev",
"description": "Superset is a data exploration platform designed to be visual, intuitive, and interactive.",
"license": "Apache-2.0",
"directories": {
"doc": "docs",
"test": "spec"
},
"name": "@superset-ui/monorepo",
"version": "0.0.0",
"description": "Superset UI",
"private": true,
"scripts": {
"tdd": "NODE_ENV=test jest --watch",
"test": "NODE_ENV=test jest",
"type": "tsc --noEmit",
"cover": "NODE_ENV=test jest --coverage",
"dev": "webpack --mode=development --colors --debug --watch",
"dev-server": "NODE_ENV=development BABEL_ENV=development node --max_old_space_size=4096 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --mode=development",
"prod": "npm run build",
"build-dev": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=development webpack --mode=development --colors",
"build-instrumented": "cross-env NODE_ENV=development BABEL_ENV=instrumented webpack --mode=development --colors",
"build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=production BABEL_ENV=production webpack --mode=production --colors",
"lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx . && npm run type",
"prettier-check": "prettier --check '{src,stylesheets}/**/*.{css,less,sass,scss}'",
"lint-fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx,.ts,tsx . && npm run clean-css && npm run type",
"clean-css": "prettier --write '{src,stylesheets}/**/*.{css,less,sass,scss}'",
"format": "prettier --write './{src,spec,stylesheets,cypress-base}/**/*{.js,.jsx,.ts,.tsx,.css,.less,.scss,.sass}'",
"prettier": "npm run format",
"check-translation": "prettier --check ../superset/translations/**/LC_MESSAGES/*.json",
"clean-translation": "prettier --write ../superset/translations/**/LC_MESSAGES/*.json",
"storybook": "NODE_ENV=development BABEL_ENV=development start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"repository": {
"type": "git",
"url": "git+https://github.com/apache/superset.git"
"build": "node ./scripts/build.js",
"build:assets": "node ./scripts/copyAssets.js",
"babel": "yarn build --no-type",
"demo": "cd packages/superset-ui-demo && yarn demo:build",
"demo:clean": "cd packages/superset-ui-demo && yarn demo:clean",
"demo:build": "cd packages/superset-ui-demo && yarn demo:build",
"storybook": "cd packages/superset-ui-demo && yarn storybook",
"build-storybook": "cd packages/superset-ui-demo && yarn build-storybook",
"chromatic": "cd packages/superset-ui-demo && yarn chromatic",
"sb": "yarn storybook",
"clean": "yarn build --clean --no-babel --no-type",
"commit": "superset-commit",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 10",
"jest": "NODE_ENV=test jest --coverage --verbose",
"lint": "esprint check",
"lint:fix": "yarn lint --fix",
"format": "yarn prettier",
"prettier": "prettier --write .",
"test": "yarn jest",
"test:watch": "yarn lint:fix && yarn jest --watch",
"type": "yarn build --no-babel",
"prepare-release": "git checkout master && git pull --rebase origin master && yarn install && yarn test",
"prerelease": "yarn build",
"release": "yarn prepare-release && lerna publish && yarn postrelease",
"postrelease": "lerna run deploy-demo",
"list-changed-packages": "lerna changed",
"manual-release": "lerna publish --force-publish && yarn postrelease",
"clean-npm-lock": "rm -rf package-lock.json ./{packages,plugins}/*/package-lock.json",
"ci:create-patch-version": "yarn clean-npm-lock && lerna version patch --yes",
"ci:create-minor-version": "yarn clean-npm-lock && lerna version minor --yes",
"ci:create-conventional-version": "yarn clean-npm-lock && lerna version --conventional-commits --create-release github --yes",
"ci:release-from-tag": "yarn clean-npm-lock && lerna publish from-package --yes",
"ci:release-conventional": "yarn clean-npm-lock && lerna publish --conventional-commits --create-release github --yes"
},
"repository": "https://github.com/apache-superset/superset-ui.git",
"keywords": [
"big",
"apache",
"superset",
"data",
"exploratory",
"analytics",
"analysis",
"visualization",
"react",
"d3",
"airbnb",
"nerds",
"database",
"flask"
"data-ui",
"vx"
],
"author": "Apache",
"bugs": {
"url": "https://github.com/apache/superset/issues"
},
"browserslist": [
"last 3 chrome versions",
"last 3 firefox versions",
"last 3 safari versions",
"last 3 edge versions"
],
"engines": {
"node": ">= 12.18.3 < 13",
"npm": ">= 6.14.8"
},
"homepage": "https://superset.apache.org/",
"license": "Apache-2.0",
"dependencies": {
"@ant-design/icons": "^4.2.2",
"@babel/runtime-corejs3": "^7.12.5",
"@data-ui/sparkline": "^0.0.84",
"@emotion/core": "^10.0.35",
"@superset-ui/chart-controls": "^0.17.5",
"@superset-ui/core": "^0.17.5",
"@superset-ui/legacy-plugin-chart-calendar": "^0.17.5",
"@superset-ui/legacy-plugin-chart-chord": "^0.17.5",
"@superset-ui/legacy-plugin-chart-country-map": "^0.17.5",
"@superset-ui/legacy-plugin-chart-event-flow": "^0.17.5",
"@superset-ui/legacy-plugin-chart-force-directed": "^0.17.5",
"@superset-ui/legacy-plugin-chart-heatmap": "^0.17.5",
"@superset-ui/legacy-plugin-chart-histogram": "^0.17.5",
"@superset-ui/legacy-plugin-chart-horizon": "^0.17.5",
"@superset-ui/legacy-plugin-chart-map-box": "^0.17.5",
"@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.5",
"@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.5",
"@superset-ui/legacy-plugin-chart-partition": "^0.17.5",
"@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.5",
"@superset-ui/legacy-plugin-chart-rose": "^0.17.5",
"@superset-ui/legacy-plugin-chart-sankey": "^0.17.5",
"@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.5",
"@superset-ui/legacy-plugin-chart-sunburst": "^0.17.5",
"@superset-ui/legacy-plugin-chart-treemap": "^0.17.5",
"@superset-ui/legacy-plugin-chart-world-map": "^0.17.5",
"@superset-ui/legacy-preset-chart-big-number": "^0.17.5",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.1",
"@superset-ui/legacy-preset-chart-nvd3": "^0.17.5",
"@superset-ui/plugin-chart-echarts": "^0.17.6",
"@superset-ui/plugin-chart-table": "^0.17.6",
"@superset-ui/plugin-chart-word-cloud": "^0.17.5",
"@superset-ui/preset-chart-xy": "^0.17.5",
"@vx/responsive": "^0.0.195",
"abortcontroller-polyfill": "^1.1.9",
"antd": "^4.9.4",
"array-move": "^2.2.1",
"bootstrap": "^3.4.1",
"bootstrap-slider": "^10.0.0",
"brace": "^0.11.1",
"chrono-node": "^1.3.11",
"classnames": "^2.2.5",
"core-js": "^3.6.5",
"d3-array": "^1.2.4",
"d3-color": "^1.2.0",
"d3-scale": "^2.1.2",
"dom-to-image": "^2.6.0",
"fontsource-fira-code": "^3.0.5",
"fontsource-inter": "^3.0.5",
"geolib": "^2.0.24",
"global-box": "^1.2.0",
"immutable": "^4.0.0-rc.12",
"interweave": "^11.2.0",
"jquery": "^3.5.1",
"js-levenshtein": "^1.1.6",
"json-bigint": "^1.0.0",
"json-stringify-pretty-compact": "^2.0.0",
"lodash": "^4.17.20",
"lodash-es": "^4.17.14",
"match-sorter": "^6.1.0",
"mathjs": "^8.0.1",
"memoize-one": "^5.1.1",
"moment": "^2.26.0",
"mousetrap": "^1.6.1",
"mustache": "^2.2.1",
"omnibar": "^2.1.1",
"polished": "^3.6.5",
"prop-types": "^15.7.2",
"query-string": "^6.13.7",
"re-resizable": "^6.6.1",
"react": "^16.13.1",
"react-ace": "^5.10.0",
"react-bootstrap": "^0.33.1",
"react-bootstrap-slider": "2.1.5",
"react-checkbox-tree": "^1.5.1",
"react-color": "^2.13.8",
"react-datetime": "^3.0.4",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^16.13.0",
"react-gravatar": "^2.6.1",
"react-hot-loader": "^4.12.20",
"react-js-cron": "^1.2.0",
"react-json-tree": "^0.11.2",
"react-jsonschema-form": "^1.2.0",
"react-loadable": "^5.5.0",
"react-markdown": "^4.3.1",
"react-redux": "^7.2.0",
"react-resize-detector": "^6.0.1-rc.1",
"react-router-dom": "^5.1.2",
"react-search-input": "^0.11.3",
"react-select": "^3.1.0",
"react-select-async-paginate": "^0.4.1",
"react-sortable-hoc": "^1.11.0",
"react-split": "^2.0.9",
"react-sticky": "^6.0.3",
"react-syntax-highlighter": "^15.3.0",
"react-table": "^7.2.1",
"react-transition-group": "^2.5.3",
"react-ultimate-pagination": "^1.2.0",
"react-virtualized": "9.19.1",
"react-virtualized-auto-sizer": "^1.0.2",
"react-virtualized-select": "^3.1.3",
"react-window": "^1.8.5",
"redux": "^4.0.5",
"redux-localstorage": "^0.4.1",
"redux-thunk": "^2.1.0",
"redux-undo": "^1.0.0-beta9-9-7",
"regenerator-runtime": "^0.13.5",
"rison": "^0.1.1",
"shortid": "^2.2.6",
"urijs": "^1.19.4",
"use-query-params": "^1.1.9"
},
"devDependencies": {
"@babel/cli": "^7.12.10",
"@babel/compat-data": "^7.12.7",
"@babel/core": "^7.12.10",
"@babel/node": "^7.12.10",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/plugin-proposal-optional-chaining": "^7.12.7",
"@airbnb/config-babel": "^3.1.0",
"@airbnb/config-jest": "^3.0.2",
"@airbnb/config-webpack": "^3.3.1",
"@babel/cli": "^7.11.5",
"@babel/compat-data": "^7.9.6",
"@babel/core": "^7.8.7",
"@babel/node": "^7.8.7",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@babel/register": "^7.12.10",
"@emotion/babel-preset-css-prop": "^10.2.1",
"@hot-loader/react-dom": "^16.13.0",
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@storybook/addon-actions": "^6.0.13",
"@storybook/addon-essentials": "^6.0.28",
"@storybook/addon-knobs": "^6.0.13",
"@storybook/addon-links": "^5.3.19",
"@storybook/addons": "^5.3.19",
"@storybook/client-api": "^6.0.21",
"@storybook/preset-typescript": "^3.0.0",
"@storybook/react": "^6.0.28",
"@svgr/webpack": "^5.4.0",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.0",
"@types/classnames": "^2.2.10",
"@types/dom-to-image": "^2.6.0",
"@types/enzyme": "^3.10.5",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/fetch-mock": "^7.3.2",
"@types/jest": "^26.0.3",
"@types/jquery": "^3.3.32",
"@types/js-levenshtein": "^1.1.0",
"@types/json-bigint": "^1.0.0",
"@types/react": "^16.9.43",
"@types/react-bootstrap": "^0.32.22",
"@types/react-dom": "^16.9.8",
"@types/react-gravatar": "^2.6.8",
"@types/react-json-tree": "^0.6.11",
"@types/react-loadable": "^5.5.4",
"@types/react-redux": "^7.1.10",
"@types/react-router-dom": "^5.1.5",
"@types/react-select": "^3.0.19",
"@types/react-sticky": "^6.0.3",
"@types/react-table": "^7.0.19",
"@types/react-ultimate-pagination": "^1.2.0",
"@types/react-virtualized": "^9.21.10",
"@types/react-window": "^1.8.2",
"@types/redux-localstorage": "^1.0.8",
"@types/redux-mock-store": "^1.0.2",
"@types/rison": "0.0.6",
"@types/sinon": "^9.0.5",
"@types/yargs": "12 - 15",
"@babel/plugin-transform-runtime": "^7.8.3",
"@babel/preset-env": "^7.8.7",
"@babel/preset-react": "^7.8.3",
"@babel/preset-typescript": "^7.12.7",
"@babel/register": "^7.8.6",
"@superset-ui/commit-config": "^0.0.9",
"@types/enzyme": "^3.10.3",
"@types/jest": "^26.0.4",
"@types/jsdom": "^12.2.4",
"@types/react": "^16.14.2",
"@types/react-test-renderer": "^16.9.2",
"@typescript-eslint/eslint-plugin": "^4.1.0",
"@typescript-eslint/parser": "^4.1.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.3",
"babel-loader": "^8.2.2",
"babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-emotion": "^10.0.33",
"babel-plugin-emotion": "^11.0.0",
"babel-plugin-jsx-remove-data-test-id": "^2.1.3",
"babel-plugin-lodash": "^3.3.4",
"cache-loader": "^1.2.2",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.0.3",
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"emotion-ts-plugin": "^0.5.3",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"babel-plugin-typescript-to-proptypes": "^1.4.2",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.1",
"enzyme-to-json": "^3.4.3",
"eslint": "^7.17.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^7.1.0",
@@ -260,38 +102,30 @@
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-testing-library": "^3.10.1",
"exports-loader": "^0.7.0",
"fetch-mock": "^7.7.3",
"file-loader": "^6.0.0",
"fork-ts-checker-webpack-plugin": "^0.4.9",
"ignore-styles": "^5.0.1",
"imports-loader": "^0.7.1",
"eslint-plugin-unicorn": "^25.0.1",
"esprint": "^0.7.0",
"fast-glob": "^3.2.4",
"fs-extra": "^9.0.0",
"global-box": "^1.2.0",
"husky": "^4.2.5",
"identity-obj-proxy": "^3.0.0",
"jest": "^26.6.3",
"jest-environment-enzyme": "^7.1.2",
"jest-enzyme": "^7.1.2",
"jest-mock-console": "^1.0.0",
"jsdom": "^16.4.0",
"less": "^3.12.2",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.4.0",
"node-fetch": "^2.6.1",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"po2json": "^0.4.5",
"lerna": "^3.15.0",
"lint-staged": "^10.0.3",
"prettier": "^2.2.1",
"react-test-renderer": "^16.9.0",
"redux-mock-store": "^1.5.4",
"sinon": "^9.0.2",
"source-map-support": "^0.5.16",
"speed-measure-webpack-plugin": "^1.2.3",
"storybook-addon-jsx": "^7.3.3",
"storybook-addon-paddings": "^3.2.0",
"style-loader": "^1.0.0",
"terser-webpack-plugin": "^1.1.0",
"thread-loader": "^1.2.0",
"transform-loader": "^0.2.3",
"react": "^16.13.1",
"react-bootstrap": "^0.33.1",
"react-dom": "^16.13.1",
"react-loadable": "^5.5.0",
"react-test-renderer": "^16.13.1",
"rimraf": "^3.0.2",
"ts-jest": "^26.4.2",
"ts-loader": "^8.0.7",
"typescript": "^4.0.3",
"url-loader": "^1.0.1",
"typescript": "^4.1.2",
"webpack": "^4.42.0",
"webpack-bundle-analyzer": "^3.6.1",
"webpack-cli": "^3.3.11",
@@ -300,21 +134,33 @@
"webpack-sources": "^1.4.3",
"yargs": "^15.4.1"
},
"stylelint": {
"rules": {
"block-opening-brace-space-before": "always",
"no-missing-end-of-source-newline": "never",
"rule-empty-line-before": [
"always",
{
"except": [
"first-nested"
],
"ignore": [
"after-comment"
]
}
]
"resolutions": {
"@types/react-bootstrap/@types/react": "^16.14.2"
},
"engines": {
"node": ">=10.10.0",
"npm": ">=6.8.0",
"yarn": ">=1.13.0"
},
"workspaces": [
"./packages/*",
"./plugins/*"
],
"browserslist": [
"last 3 chrome versions",
"last 3 firefox versions",
"last 3 safari versions",
"last 3 edge versions"
],
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "./scripts/commitlint.js HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"*.{js,jsx,ts,tsx,json,md}": [
"prettier --write"
]
}
}

View File

@@ -0,0 +1 @@
* text=auto

View File

@@ -0,0 +1,33 @@
# generator-superset
[![Version](https://img.shields.io/npm/v/@superset-ui/generator-superset.svg?style=flat)](https://www.npmjs.com/package/@superset-ui/generator-superset)
[![David (path)](https://img.shields.io/david/apache-superset/superset-ui.svg?path=packages%2Fgenerator-superset&style=flat-square)](https://david-dm.org/apache-superset/superset-ui?path=packages/generator-superset)
> Scaffolder for Superset
## Installation
First, install [Yeoman](http://yeoman.io) and `generator-superset` using
[npm](https://www.npmjs.com/) (we assume you have pre-installed [node.js](https://nodejs.org/)).
```bash
npm install -g yo
npm install -g @superset-ui/generator-superset
```
## Usage
Generate a new package or visualization plugin in `@superset-ui`
```bash
cd superset-ui/packages
mkdir superset-ui-new-package
cd superset-ui-new-package
yo @superset-ui/superset
```
## License
Apache-2.0
[learn more about Yeoman](http://yeoman.io/).

View File

@@ -0,0 +1,41 @@
/* eslint-disable sort-keys */
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
module.exports = class extends Generator {
async prompting() {
// Have Yeoman greet the user.
this.log(yosay(`Welcome to the rad ${chalk.red('generator-superset')} generator!`));
this.option('skipInstall');
this.answers = await this.prompt([
{
type: 'list',
name: 'subgenerator',
message: 'What do you want to do?',
choices: [
{
name: 'Create superset-ui core package',
value: 'package',
},
{
name: 'Create superset-ui chart plugin package',
value: 'plugin-chart',
},
],
},
]);
}
configuring() {
// Redirect the default 'app' generator
// to 'package' subgenerator
// until there are multiple subgenerators
// then this can be changed into a menu to select
// subgenerator.
this.composeWith(require.resolve(`../${this.answers.subgenerator}`));
}
};

View File

@@ -0,0 +1,56 @@
/* eslint-disable sort-keys */
const Generator = require('yeoman-generator');
const _ = require('lodash');
module.exports = class extends Generator {
async prompting() {
this.option('skipInstall');
this.answers = await this.prompt([
{
type: 'input',
name: 'name',
message: 'Package name:',
default: _.kebabCase(this.appname.replace('superset ui', '').trim()), // Default to current folder name
},
{
type: 'list',
name: 'language',
message: 'Choose language',
default: 'typescript',
choices: [
{
name: 'typescript',
value: 'typescript',
short: 't',
},
{
name: 'javascript',
value: 'javascript',
short: 'j',
},
],
},
]);
}
writing() {
this.fs.copyTpl(
this.templatePath('_package.json'),
this.destinationPath('package.json'),
this.answers,
);
this.fs.copyTpl(
this.templatePath('README.md'),
this.destinationPath('README.md'),
this.answers,
);
const ext = this.answers.language === 'typescript' ? 'ts' : 'js';
this.fs.copy(this.templatePath('src/index.txt'), this.destinationPath(`src/index.${ext}`));
this.fs.copy(
this.templatePath('test/index.txt'),
this.destinationPath(`test/index.test.${ext}`),
);
}
};

View File

@@ -0,0 +1,27 @@
## @superset-ui/<%= name %>
[![Version](https://img.shields.io/npm/v/@superset-ui/<%= name
%>.svg?style=flat)](https://img.shields.io/npm/v/@superset-ui/<%= name %>.svg?style=flat)
[![David (path)](https://img.shields.io/david/apache-superset/superset-ui.svg?path=packages%2Fsuperset-ui-<%=
name
%>&style=flat-square)](https://david-dm.org/apache-superset/superset-ui?path=packages/superset-ui-<%=
name %>)
Description
#### Example usage
```js
import { xxx } from '@superset-ui/<%= name %>';
```
#### API
`fn(args)`
- Do something
### Development
`@data-ui/build-config` is used to manage the build configuration for this package including babel
builds, jest testing, eslint, and prettier.

View File

@@ -0,0 +1,23 @@
{
"name": "@superset-ui/<%= name %>",
"version": "0.0.0",
"description": "Superset UI <%= name %>",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"files": ["esm", "lib"],
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"keywords": ["superset"],
"author": "Superset",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,2 @@
const x = 1;
export default x;

View File

@@ -0,0 +1,5 @@
describe('My Test', () => {
it('tests something', () => {
expect(1).toEqual(1);
});
});

View File

@@ -0,0 +1,99 @@
/* eslint-disable sort-keys */
const Generator = require('yeoman-generator');
const _ = require('lodash');
module.exports = class extends Generator {
async prompting() {
this.option('skipInstall');
this.answers = await this.prompt([
{
type: 'input',
name: 'packageName',
message: 'Package name:',
// Default to current folder name
default: _.kebabCase(this.appname.replace('plugin chart', '').trim()),
},
{
type: 'input',
name: 'description',
message: 'Description:',
// Default to current folder name
default: _.upperFirst(_.startCase(this.appname.replace('plugin chart', '').trim())),
},
{
type: 'list',
name: 'componentType',
message: 'What type of React component would you like?',
choices: [
{
name: 'Class component',
value: 'class',
},
{
name: 'Function component (with hooks)',
value: 'function',
},
],
},
{
type: 'list',
name: 'chartType',
message: 'What type of chart would you like?',
choices: [
{
name: 'Time-series chart',
value: 'timeseries',
},
{
name: 'Regular chart',
value: 'regular',
},
],
},
{
type: 'confirm',
name: 'addBadges',
message: "Add superset-ui badges to your plugin's README.md",
default: true,
},
]);
}
writing() {
// 'hello-world' -> 'HelloWorld'
const packageLabel = _.upperFirst(_.camelCase(this.answers.packageName));
// 'hello-world' -> 'Hello World'
const pluginName = _.startCase(_.camelCase(this.answers.packageName));
const params = {
...this.answers,
packageLabel,
pluginName,
};
[
['package.erb', 'package.json'],
['tsconfig.json', 'tsconfig.json'],
['README.erb', 'README.md'],
['src/index.erb', 'src/index.ts'],
['src/plugin/buildQuery.erb', 'src/plugin/buildQuery.ts'],
['src/plugin/controlPanel.erb', 'src/plugin/controlPanel.ts'],
['src/plugin/index.erb', 'src/plugin/index.ts'],
['src/plugin/transformProps.erb', 'src/plugin/transformProps.ts'],
['src/types.erb', 'src/types.ts'],
['src/MyChart.erb', `src/${packageLabel}.tsx`],
['test/index.erb', 'test/index.test.ts'],
['test/plugin/buildQuery.test.erb', 'test/plugin/buildQuery.test.ts'],
['test/plugin/transformProps.test.erb', 'test/plugin/transformProps.test.ts'],
].forEach(([src, dest]) => {
this.fs.copyTpl(this.templatePath(src), this.destinationPath(dest), params);
});
['types/external.d.ts', 'src/images/thumbnail.png'].forEach(file => {
this.fs.copy(this.templatePath(file), this.destinationPath(file));
});
}
};

View File

@@ -0,0 +1,54 @@
## @superset-ui/plugin-chart-<%= packageName %>
<%if (addBadges) { %>[![Version](https://img.shields.io/npm/v/@superset-ui/plugin-chart-<%= packageName %>.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/plugin-chart-<%= packageName %>)<% } %>
This plugin provides <%= description %> for Superset.
### Usage
Configure `key`, which can be any `string`, and register the plugin. This `key` will be used to lookup this chart throughout the app.
```js
import <%= packageLabel %>ChartPlugin from '@superset-ui/plugin-chart-<%= packageName %>';
new <%= packageLabel %>ChartPlugin()
.configure({ key: '<%= packageName %>' })
.register();
```
Then use it via `SuperChart`. See [storybook](https://apache-superset.github.io/superset-ui/?selectedKind=plugin-chart-<%= packageName %>) for more details.
```js
<SuperChart
chartType="<%= packageName %>"
width={600}
height={600}
formData={...}
queriesData={[{
data: {...},
}]}
/>
```
### File structure generated
```
├── package.json
├── README.md
├── tsconfig.json
├── src
│   ├── <%= packageLabel %>.tsx
│   ├── images
│   │   └── thumbnail.png
│   ├── index.ts
│   ├── plugin
│   │   ├── buildQuery.ts
│   │   ├── controlPanel.ts
│   │   ├── index.ts
│   │   └── transformProps.ts
│   └── types.ts
├── test
│   └── index.test.ts
└── types
└── external.d.ts
```

View File

@@ -0,0 +1,39 @@
{
"name": "@superset-ui/plugin-chart-<%= packageName %>",
"version": "0.0.0",
"description": "Superset Chart - <%= description %>",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"files": [
"esm",
"lib"
],
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"keywords": [
"superset"
],
"author": "Superset",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@superset-ui/core": "^0.15.2",
"@superset-ui/chart-controls": "^0.15.2"
},
"peerDependencies": {
"react": "^16.13.1"
},
"devDependencies": {
"@types/jest": "^26.0.0",
"jest": "^26.0.1"
}
}

View File

@@ -0,0 +1,113 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { <%if (componentType == 'class') { %>PureComponent<% } %><%if (componentType == 'function') { %>useEffect<% } %>, createRef } from 'react';
import { styled } from '@superset-ui/core';
import { <%= packageLabel %>Props, <%= packageLabel %>StylesProps } from './types';
// The following Styles component is a <div> element, which has been styled using Emotion
// For docs, visit https://emotion.sh/docs/styled
// Theming variables are provided for your use via a ThemeProvider
// imported from @superset-ui/core. For variables available, please visit
// https://github.com/apache-superset/superset-ui/blob/master/packages/superset-ui-core/src/style/index.ts
const Styles = styled.div<<%= packageLabel %>StylesProps>`
background-color: ${({ theme }) => theme.colors.secondary.light2};
padding: ${({ theme }) => theme.gridUnit * 4}px;
border-radius: ${({ theme }) => theme.gridUnit * 2}px;
height: ${({ height }) => height};
width: ${({ width }) => width};
overflow-y: scroll;
h3 {
/* You can use your props to control CSS! */
font-size: ${({ theme, headerFontSize }) => theme.typography.sizes[headerFontSize]};
font-weight: ${({ theme, boldText }) => theme.typography.weights[boldText ? 'bold' : 'normal']};
}
`;
/**
* ******************* WHAT YOU CAN BUILD HERE *******************
* In essence, a chart is given a few key ingredients to work with:
* * Data: provided via `props.data`
* * A DOM element
* * FormData (your controls!) provided as props by transformProps.ts
*/
<%if (componentType == 'class') { %>export default class <%= packageLabel %> extends PureComponent<<%= packageLabel %>Props> {
// Often, you just want to get a hold of the DOM and go nuts.
// Here, you can do that with createRef, and componentDidMount.
rootElem = createRef<HTMLDivElement>();
componentDidMount() {
const root = this.rootElem.current as HTMLElement;
console.log('Plugin element', root);
}
render() {
// height and width are the height and width of the DOM element as it exists in the dashboard.
// There is also a `data` prop, which is, of course, your DATA 🎉
console.log('Approach 1 props', this.props);
const { data, height, width } = this.props;
console.log('Plugin props', this.props);
return (
<Styles
ref={this.rootElem}
boldText={this.props.boldText}
headerFontSize={this.props.headerFontSize}
height={height}
width={width}
>
<h3>{this.props.headerText}</h3>
<pre>{JSON.stringify(data, null, 2)}</pre>
</Styles>
);
}
}<% } %><%if (componentType == 'function') { %>export default function <%= packageLabel %>(props: <%= packageLabel %>Props) {
// height and width are the height and width of the DOM element as it exists in the dashboard.
// There is also a `data` prop, which is, of course, your DATA 🎉
const { data, height, width } = props;
const rootElem = createRef<HTMLDivElement>();
// Often, you just want to get a hold of the DOM and go nuts.
// Here, you can do that with createRef, and the useEffect hook.
useEffect(() => {
const root = rootElem.current as HTMLElement;
console.log('Plugin element', root);
});
console.log('Plugin props', props);
return (
<Styles
ref={rootElem}
boldText={props.boldText}
headerFontSize={props.headerFontSize}
height={height}
width={width}
>
<h3>{props.headerText}</h3>
<pre>${JSON.stringify(data, null, 2)}</pre>
</Styles>
);
}<% } %>

View File

@@ -0,0 +1,27 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// eslint-disable-next-line import/prefer-default-export
export { default as <%= packageLabel %>ChartPlugin } from './plugin';
/**
* Note: this file exports the default export from <%= packageLabel %>.tsx.
* If you want to export multiple visualization modules, you will need to
* either add additional plugin folders (similar in structure to ./plugin)
* OR export multiple instances of `ChartPlugin` extensions in ./plugin/index.ts
* which in turn load exports from <%= packageLabel %>.tsx
*/

View File

@@ -0,0 +1,179 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t, validateNonEmpty } from '@superset-ui/core';
import { ControlPanelConfig } from '@superset-ui/chart-controls';
const config: ControlPanelConfig = {
/**
* The control panel is split into two tabs: "Query" and
* "Chart Options". The controls that define the inputs to
* the chart data request, such as columns and metrics, usually
* reside within "Query", while controls that affect the visual
* appearance or functionality of the chart are under the
* "Chart Options" section.
*
* There are several predefined controls that can be used.
* Some examples:
* - groupby: columns to group by (tranlated to GROUP BY statement)
* - series: same as groupby, but single selection.
* - metrics: multiple metrics (translated to aggregate expression)
* - metric: sane as metrics, but single selection
* - adhoc_filters: filters (translated to WHERE or HAVING
* depending on filter type)
* - row_limit: maximum number of rows (translated to LIMIT statement)
*
* If a control panel has both a `series` and `groupby` control, and
* the user has chosen `col1` as the value for the `series` control,
* and `col2` and `col3` as values for the `groupby` control,
* the resulting query will contain three `groupby` columns. This is because
* we considered `series` control a `groupby` query field and its value
* will automatically append the `groupby` field when the query is generated.
*
* It is also possible to define custom controls by importing the
* necessary dependencies and overriding the default parameters, which
* can then be placed in the `controlSetRows` section
* of the `Query` section instead of a predefined control.
*
* import { validateNonEmpty } from '@superset-ui/core';
* import {
* sharedControls,
* ControlConfig,
* ControlPanelConfig,
* } from '@superset-ui/chart-controls';
*
* const myControl: ControlConfig<'SelectControl'> = {
* name: 'secondary_entity',
* config: {
* ...sharedControls.entity,
* type: 'SelectControl',
* label: t('Secondary Entity'),
* mapStateToProps: state => ({
* sharedControls.columnChoices(state.datasource)
* .columns.filter(c => c.groupby)
* })
* validators: [validateNonEmpty],
* },
* }
*
* In addition to the basic drop down control, there are several predefined
* control types (can be set via the `type` property) that can be used. Some
* commonly used examples:
* - SelectControl: Dropdown to select single or multiple values,
usually columns
* - MetricsControl: Dropdown to select metrics, triggering a modal
to define Metric details
* - AdhocFilterControl: Control to choose filters
* - CheckboxControl: A checkbox for choosing true/false values
* - SliderControl: A slider with min/max values
* - TextControl: Control for text data
*
* For more control input types, check out the `incubator-superset` repo
* and open this file: superset-frontend/src/explore/components/controls/index.js
*
* To ensure all controls have been filled out correctly, the following
* validators are provided
* by the `@superset-ui/core/lib/validator`:
* - validateNonEmpty: must have at least one value
* - validateInteger: must be an integer value
* - validateNumber: must be an intger or decimal value
*/
// For control input types, see: superset-frontend/src/explore/components/controls/index.js
controlPanelSections: [
{
label: t('Query'),
expanded: true,
controlSetRows: [['groupby'], ['metrics'], ['adhoc_filters'], ['row_limit', null]],
},
{
label: t('Hello Controls!'),
expanded: true,
controlSetRows: [
[
{
name: 'header_text',
config: {
type: 'TextControl',
default: 'Hello, World!',
renderTrigger: true,
// ^ this makes it apply instantaneously, without triggering a "run query" button
label: t('Header Text'),
description: t('The text you want to see in the header'),
},
},
],
[
{
name: 'bold_text',
config: {
type: 'CheckboxControl',
label: t('Bold Text'),
renderTrigger: true,
default: true,
description: t('A checkbox to make the '),
},
},
],
[
{
name: 'header_font_size',
config: {
type: 'SelectControl',
label: t('Font Size'),
default: 'xl',
choices: [
// [value, label]
['xxs', 'xx-small'],
['xs', 'x-small'],
['s', 'small'],
['m', 'medium'],
['l', 'large'],
['xl', 'x-large'],
['xxl', 'xx-large'],
],
renderTrigger: true,
description: t('The size of your header font'),
},
},
],
],
},
],
<%if (chartType === 'timeseries') { %> // Time series charts need to override the `druidTimeSeries` and `sqlaTimeSeries`
// sections to add the time grain dropdown.
sectionOverrides: {
druidTimeSeries: {
controlSetRows: [['granularity', 'druid_time_origin'], ['time_range']],
},
sqlaTimeSeries: {
controlSetRows: [['granularity_sqla', 'time_grain_sqla'], ['time_range']],
},
},<% } %>
controlOverrides: {
series: {
validators: [validateNonEmpty],
clearable: false,
},
row_limit: {
default: 100,
},
},
};
export default config;

View File

@@ -0,0 +1,51 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
import buildQuery from './buildQuery';
import controlPanel from './controlPanel';
import transformProps from './transformProps';
import thumbnail from '../images/thumbnail.png';
export default class <%= packageLabel %>ChartPlugin extends ChartPlugin {
/**
* The constructor is used to pass relevant metadata and callbacks that get
* registered in respective registries that are used throughout the library
* and application. A more thorough description of each property is given in
* the respective imported file.
*
* It is worth noting that `buildQuery` and is optional, and only needed for
* advanced visualizations that require either post processing operations
* (pivoting, rolling aggregations, sorting etc) or submitting multiple queries.
*/
constructor() {
const metadata = new ChartMetadata({
description: '<%= description %>',
name: t('<%= pluginName %>'),
thumbnail,
});
super({
buildQuery,
controlPanel,
loadChart: () => import('../<%= packageLabel %>'),
metadata,
transformProps,
});
}
}

View File

@@ -0,0 +1,72 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ChartProps, TimeseriesDataRecord } from '@superset-ui/core';
export default function transformProps(chartProps: ChartProps) {
/**
* This function is called after a successful response has been
* received from the chart data endpoint, and is used to transform
* the incoming data prior to being sent to the Visualization.
*
* The transformProps function is also quite useful to return
* additional/modified props to your data viz component. The formData
* can also be accessed from your <%= packageLabel %>.tsx file, but
* doing supplying custom props here is often handy for integrating third
* party libraries that rely on specific props.
*
* A description of properties in `chartProps`:
* - `height`, `width`: the height/width of the DOM element in which
* the chart is located
* - `formData`: the chart data request payload that was sent to the
* backend.
* - `queriesData`: the chart data response payload that was received
* from the backend. Some notable properties of `queriesData`:
* - `data`: an array with data, each row with an object mapping
* the column/alias to its value. Example:
* `[{ col1: 'abc', metric1: 10 }, { col1: 'xyz', metric1: 20 }]`
* - `rowcount`: the number of rows in `data`
* - `query`: the query that was issued.
*
* Please note: the transformProps function gets cached when the
* application loads. When making changes to the `transformProps`
* function during development with hot reloading, changes won't
* be seen until restarting the development server.
*/
const { width, height, formData, queriesData } = chartProps;
const { boldText, headerFontSize, headerText } = formData;
const data = queriesData[0].data as TimeseriesDataRecord[];
console.log('formData via TransformProps.ts', formData);
return {
width,
height,
<%if (chartType === 'timeseries') { %>
data: data.map(item => ({
...item,
// convert epoch to native Date
// eslint-disable-next-line no-underscore-dangle
__timestamp: new Date(item.__timestamp as number),
})),<% } else { %> data,<% } %>
// and now your control data, manipulated as needed, and passed through as props!
boldText,
headerFontSize,
headerText,
};
}

View File

@@ -0,0 +1,40 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { QueryFormData, supersetTheme, TimeseriesDataRecord } from '@superset-ui/core';
export interface <%= packageLabel %>StylesProps {
height: number;
width: number;
headerFontSize: keyof typeof supersetTheme.typography.sizes;
boldText: boolean;
}
interface <%= packageLabel %>CustomizeProps {
headerText: string;
}
export type <%= packageLabel %>QueryFormData = QueryFormData &
<%= packageLabel %>StylesProps &
<%= packageLabel %>CustomizeProps;
export type <%= packageLabel %>Props = <%= packageLabel %>StylesProps &
<%= packageLabel %>CustomizeProps & {
data: TimeseriesDataRecord[];
// add typing here for the props you pass in from transformProps.ts!
};

View File

@@ -0,0 +1,33 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { <%= packageLabel %>ChartPlugin } from '../src';
/**
* The example tests in this file act as a starting point, and
* we encourage you to build more. These tests check that the
* plugin loads properly, and focus on `transformProps`
* to ake sure that data, controls, and props are all
* treated correctly (e.g. formData from plugin controls
* properly transform the data and/or any resulting props).
*/
describe('@superset-ui/plugin-chart-<%= packageName %>', () => {
it('exists', () => {
expect(<%= packageLabel %>ChartPlugin).toBeDefined();
});
});

View File

@@ -0,0 +1,16 @@
import buildQuery from '../../src/plugin/buildQuery';
describe('<%= packageLabel %> buildQuery', () => {
const formData = {
datasource: '5__table',
granularity_sqla: 'ds',
series: 'foo',
viz_type: 'my_chart',
};
it('should build groupby with series in form data', () => {
const queryContext = buildQuery(formData);
const [query] = queryContext.queries;
expect(query.groupby).toEqual(['foo']);
});
});

View File

@@ -0,0 +1,34 @@
import { ChartProps } from '@superset-ui/core';
import transformProps from '../../src/plugin/transformProps';
describe('<%= packageLabel %> tranformProps', () => {
const formData = {
colorScheme: 'bnbColors',
datasource: '3__table',
granularity_sqla: 'ds',
metric: 'sum__num',
series: 'name',
boldText: true,
headerFontSize: 'xs',
headerText: 'my text',
};
const chartProps = new ChartProps({
formData,
width: 800,
height: 600,
queriesData: [{
data: [{ name: 'Hulk', sum__num: 1<%if (chartType === 'timeseries') { %>, __timestamp: 599616000000<% } %> }],
}],
});
it('should tranform chart props for viz', () => {
expect(transformProps(chartProps)).toEqual({
width: 800,
height: 600,
boldText: true,
headerFontSize: 'xs',
headerText: 'my text',
data: [{ name: 'Hulk', sum__num: 1<%if (chartType === 'timeseries') { %>, __timestamp: new Date(599616000000)<% } %> }],
});
});
});

View File

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"declarationDir": "lib",
"outDir": "lib",
"rootDir": "src"
},
"exclude": [
"lib",
"test"
],
"extends": "../../tsconfig.options.json",
"include": [
"src/**/*",
"types/**/*",
"../../types/**/*"
],
"references": [
{
"path": "../../packages/superset-ui-chart-controls"
},
{
"path": "../../packages/superset-ui-core"
}
]
}

View File

@@ -0,0 +1,4 @@
declare module '*.png' {
const value: any;
export default value;
}

View File

@@ -0,0 +1,41 @@
{
"name": "@superset-ui/generator-superset",
"version": "0.17.7",
"description": "Scaffolder for Superset",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui/issues"
},
"homepage": "https://github.com/apache-superset/superset-ui#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui.git"
},
"author": "Superset",
"files": [
"generators"
],
"main": "generators/index.js",
"keywords": [
"yeoman",
"generator",
"superset",
"yeoman-generator"
],
"devDependencies": {
"yeoman-assert": "^3.1.0",
"yeoman-test": "^2.0.0"
},
"engines": {
"npm": ">= 4.0.0"
},
"dependencies": {
"chalk": "^4.0.0",
"lodash": "^4.17.11",
"yeoman-generator": "^4.0.0",
"yosay": "^2.0.2"
},
"license": "Apache-2.0",
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,35 @@
const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
describe('generator-superset:app', () => {
let dir;
beforeAll(() => {
dir = process.cwd();
return helpers.run(path.join(__dirname, '../generators/app')).withPrompts({
subgenerator: 'package',
name: 'my-package',
});
});
/*
* Change working directory back to original working directory
* after the test has completed.
* yeoman tests switch to tmp directory and write files there.
* Usually this is fine for solo package.
* However, for a monorepo like this one,
* it made jest confuses with current directory
* (being in tmp directory instead of superset-ui root)
* and interferes with other tests in sibling packages
* that are run after the yeoman tests.
*/
afterAll(() => {
process.chdir(dir);
});
it('creates files', () => {
assert.file(['package.json', 'README.md', 'src/index.ts', 'test/index.test.ts']);
});
});

View File

@@ -0,0 +1,52 @@
const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
describe('generator-superset:package', () => {
let dir;
beforeAll(() => {
dir = process.cwd();
});
/*
* Change working directory back to original working directory
* after the test has completed.
* yeoman tests switch to tmp directory and write files there.
* Usually this is fine for solo package.
* However, for a monorepo like this one,
* it made jest confuses with current directory
* (being in tmp directory instead of superset-ui root)
* and interferes with other tests in sibling packages
* that are run after the yeoman tests.
*/
afterAll(() => {
process.chdir(dir);
});
describe('typescript', () => {
beforeAll(() =>
helpers
.run(path.join(__dirname, '../generators/package'))
.withPrompts({ name: 'my-package', language: 'typescript' })
.withOptions({ skipInstall: true }),
);
it('creates files', () => {
assert.file(['package.json', 'README.md', 'src/index.ts', 'test/index.test.ts']);
});
});
describe('javascript', () => {
beforeAll(() =>
helpers
.run(path.join(__dirname, '../generators/package'))
.withPrompts({ name: 'my-package', language: 'javascript' })
.withOptions({ skipInstall: true }),
);
it('creates files', () => {
assert.file(['package.json', 'README.md', 'src/index.js', 'test/index.test.js']);
});
});
});

View File

@@ -0,0 +1,50 @@
/* eslint-env node */
const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
describe('generator-superset:plugin-chart', () => {
let dir;
beforeAll(() => {
dir = process.cwd();
return helpers
.run(path.join(__dirname, '../generators/plugin-chart'))
.withPrompts({ packageName: 'cold-map', description: 'Cold Map' })
.withOptions({ skipInstall: true });
});
/*
* Change working directory back to original working directory
* after the test has completed.
* yeoman tests switch to tmp directory and write files there.
* Usually this is fine for solo package.
* However, for a monorepo like this one,
* it made jest confuses with current directory
* (being in tmp directory instead of superset-ui root)
* and interferes with other tests in sibling packages
* that are run after the yeoman tests.
*/
afterAll(() => {
process.chdir(dir);
});
it('creates files', () => {
assert.file([
'package.json',
'README.md',
'src/plugin/buildQuery.ts',
'src/plugin/controlPanel.ts',
'src/plugin/index.ts',
'src/plugin/transformProps.ts',
'src/ColdMap.tsx',
'src/index.ts',
'test/index.test.ts',
'test/plugin/buildQuery.test.ts',
'test/plugin/transformProps.test.ts',
'types/external.d.ts',
'src/images/thumbnail.png',
]);
});
});

View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"composite": false,
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": "."
},
"extends": "../../../tsconfig.options.json",
"include": [
"**/*",
"../types/**/*",
"../../../types/**/*"
],
"references": [
{
"path": ".."
}
]
}

View File

@@ -0,0 +1,30 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
**/*{.,-}min.js
**/*.sh
coverage/**
dist/*
images/*
node_modules/*
node_modules*/*
stylesheets/*
vendor/*
docs/*
src/dashboard/deprecated/*
src/temp/*
**/node_modules
*.d.ts

View File

@@ -0,0 +1,254 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
module.exports = {
extends: [
'airbnb',
'prettier',
'prettier/react',
'plugin:react-hooks/recommended',
],
parser: 'babel-eslint',
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
},
},
env: {
browser: true,
},
settings: {
'import/resolver': 'webpack',
react: {
version: 'detect',
},
},
plugins: ['prettier', 'react'],
overrides: [
{
files: ['cypress-base/**/*'],
rules: {
'import/no-unresolved': 0,
'global-require': 0,
},
},
{
files: ['webpack*.js'],
env: {
node: true,
},
settings: {
'import/resolver': {
node: {},
},
},
},
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
extends: [
'airbnb',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/@typescript-eslint',
'prettier/react',
],
plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'react'],
rules: {
'@typescript-eslint/ban-ts-ignore': 0,
'@typescript-eslint/ban-ts-comment': 0, // disabled temporarily
'@typescript-eslint/ban-types': 0, // disabled temporarily
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-use-before-define': 1, // disabled temporarily
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
camelcase: 0,
'class-methods-use-this': 0,
curly: 1,
'func-names': 0,
'guard-for-in': 0,
'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
'import/extensions': [
'error',
{
'.ts': 'always',
'.tsx': 'always',
'.json': 'always',
},
],
'import/no-named-as-default-member': 0,
'import/prefer-default-export': 0,
indent: 0,
'jsx-a11y/anchor-is-valid': 1,
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
'new-cap': 0,
'no-bitwise': 0,
'no-continue': 0,
'no-mixed-operators': 0,
'no-multi-assign': 0,
'no-multi-spaces': 0,
'no-prototype-builtins': 0,
'no-restricted-properties': 0,
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'antd',
message:
'Please import Ant components from the index of common/components',
},
],
},
],
'no-shadow': 0, // re-enable up for discussion
'no-use-before-define': 0, // disabled temporarily
'padded-blocks': 0,
'prefer-arrow-callback': 0,
'prefer-destructuring': ['error', { object: true, array: false }],
'react/destructuring-assignment': 0, // re-enable up for discussion
'react/forbid-prop-types': 0,
'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
'react/jsx-fragments': 1,
'react/jsx-no-bind': 0,
'react/jsx-props-no-spreading': 0, // re-enable up for discussion
'react/no-array-index-key': 0,
'react/no-string-refs': 0,
'react/no-unescaped-entities': 0,
'react/no-unused-prop-types': 0,
'react/prop-types': 0,
'react/require-default-props': 0,
'react/sort-comp': 0, // TODO: re-enable in separate PR
'react/static-property-placement': 0, // re-enable up for discussion
'prettier/prettier': 'error',
},
settings: {
'import/resolver': {
webpack: {},
typescript: {},
},
react: {
version: 'detect',
},
},
},
{
files: ['*.stories.jsx', '*.stories.tsx'],
rules: {
// this is to keep eslint from complaining about storybook addons,
// since they are included as dev dependencies rather than direct dependencies.
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true },
],
},
},
{
files: [
'src/**/*.test.ts',
'src/**/*.test.tsx',
'src/**/*.test.js',
'src/**/*.test.jsx',
],
plugins: ['jest', 'jest-dom', 'no-only-tests'],
env: {
'jest/globals': true,
},
extends: ['plugin:jest/recommended', 'plugin:testing-library/react'],
rules: {
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true },
],
'jest/consistent-test-it': 'error',
'no-only-tests/no-only-tests': 'error',
},
},
],
rules: {
camelcase: [
'error',
{
allow: ['^UNSAFE_'],
properties: 'never',
},
],
'class-methods-use-this': 0,
curly: 1,
'func-names': 0,
'guard-for-in': 0,
'import/extensions': [
'error',
{
'.js': 'always',
'.jsx': 'always',
'.ts': 'always',
'.tsx': 'always',
'.json': 'always',
},
],
'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
'import/prefer-default-export': 0,
indent: 0,
'jsx-a11y/anchor-is-valid': 1,
'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
'new-cap': 0,
'no-bitwise': 0,
'no-continue': 0,
'no-mixed-operators': 0,
'no-multi-assign': 0,
'no-multi-spaces': 0,
'no-prototype-builtins': 0,
'no-restricted-properties': 0,
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'antd',
message:
'Please import Ant components from the index of common/components',
},
],
},
],
'no-shadow': 0, // re-enable up for discussion
'padded-blocks': 0,
'prefer-arrow-callback': 0,
'prefer-object-spread': 1,
'prefer-destructuring': ['error', { object: true, array: false }],
'react/destructuring-assignment': 0, // re-enable up for discussion
'react/forbid-prop-types': 0,
'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
'react/jsx-fragments': 1,
'react/jsx-no-bind': 0,
'react/jsx-props-no-spreading': 0, // re-enable up for discussion
'react/no-array-index-key': 0,
'react/no-string-refs': 0,
'react/no-unescaped-entities': 0,
'react/no-unused-prop-types': 0,
'react/prop-types': 0,
'react/require-default-props': 0,
'react/sort-comp': 0, // TODO: re-enable in separate PR
'react/static-property-placement': 0, // disabled temporarily
'prettier/prettier': 'error',
},
};

View File

@@ -0,0 +1,4 @@
coverage/*
cypress/screenshots
cypress/videos
src/temp

View File

@@ -0,0 +1 @@
v12.19.0

View File

@@ -0,0 +1,84 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const packageConfig = require('./package.json');
module.exports = {
sourceMaps: true,
sourceType: 'module',
retainLines: true,
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
loose: true,
modules: false,
shippedProposals: true,
targets: packageConfig.browserslist,
},
],
[
'@babel/preset-react',
{ development: process.env.BABEL_ENV === 'development' },
],
],
plugins: [
'lodash',
'@babel/plugin-syntax-dynamic-import',
['@babel/plugin-proposal-class-properties', { loose: true }],
['@babel/plugin-proposal-optional-chaining', { loose: true }],
['@babel/plugin-proposal-private-methods', { loose: true }],
['@babel/plugin-transform-runtime', { corejs: 3 }],
'react-hot-loader/babel',
],
env: {
// Setup a different config for tests as they run in node instead of a browser
test: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
loose: true,
shippedProposals: true,
modules: 'commonjs',
targets: { node: 'current' },
},
],
],
plugins: ['babel-plugin-dynamic-import-node'],
},
// build instrumented code for testing code coverage with Cypress
instrumented: {
plugins: ['istanbul'],
},
production: {
plugins: [
[
'babel-plugin-jsx-remove-data-test-id',
{
attributes: 'data-test',
},
],
],
},
},
};

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

Before

Width:  |  Height:  |  Size: 459 KiB

After

Width:  |  Height:  |  Size: 459 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

Before

Width:  |  Height:  |  Size: 702 KiB

After

Width:  |  Height:  |  Size: 702 KiB

View File

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View File

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 328 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

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