From d2c9abe767f8232fc91700a7323db2d90c9ad116 Mon Sep 17 00:00:00 2001 From: cccs-jc Date: Fri, 12 Mar 2021 20:46:46 +0000 Subject: [PATCH 1/6] explain how docker uses local files --- superset-frontend/cccs-viz/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/superset-frontend/cccs-viz/README.md b/superset-frontend/cccs-viz/README.md index 7cdb0dbf52b3b..1287ea012f7cf 100644 --- a/superset-frontend/cccs-viz/README.md +++ b/superset-frontend/cccs-viz/README.md @@ -113,7 +113,8 @@ Make sure to point package install dir ``` -You can test that the cccs-viz plugins will build in docker. +It's important to know that the docker-compose uses the files of the host system so you absolutely need to build your cccs-viz inside your git clone. + This will create the esm and lib files. ```bash @@ -123,7 +124,7 @@ npm install yarn build ``` -Build the frontend +The same goes for the frontend it will use those files so you need to build the frontend ``` cd superset/superset-frontend From 616a5f2444f7cb73d32a6838675828d1865364e4 Mon Sep 17 00:00:00 2001 From: cccs-jc Date: Sat, 13 Mar 2021 20:26:56 +0000 Subject: [PATCH 2/6] support default viz --- superset-frontend/src/explore/store.js | 2 +- superset/views/base.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/superset-frontend/src/explore/store.js b/superset-frontend/src/explore/store.js index 9b33aaa49f6a9..9f12dc172b409 100644 --- a/superset-frontend/src/explore/store.js +++ b/superset-frontend/src/explore/store.js @@ -41,7 +41,7 @@ export function getControlsState(state, inputFormData) { * */ // Getting a list of active control names for the current viz const formData = { ...inputFormData }; - const vizType = formData.viz_type || 'table'; + const vizType = formData.viz_type || state.common.conf.DEFAULT_EXPLORER_VIZ || 'table'; handleDeprecatedControls(formData); diff --git a/superset/views/base.py b/superset/views/base.py index 69c9383ffccc1..173751b0a6439 100644 --- a/superset/views/base.py +++ b/superset/views/base.py @@ -74,6 +74,7 @@ "DISABLE_DATASET_SOURCE_EDIT", "ENABLE_JAVASCRIPT_CONTROLS", "DEFAULT_SQLLAB_LIMIT", + "DEFAULT_EXPLORER_VIZ", "SQL_MAX_ROW", "SUPERSET_WEBSERVER_DOMAINS", "SQLLAB_SAVE_WARNING_MESSAGE", From 8e792c7e011ef230394a0d1ac655f287646de646 Mon Sep 17 00:00:00 2001 From: cccs-jc Date: Sat, 13 Mar 2021 20:33:58 +0000 Subject: [PATCH 3/6] configure better defaults for hello_world --- .../src/plugin/controlPanel.ts | 59 ++++++------------- 1 file changed, 17 insertions(+), 42 deletions(-) diff --git a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts index 7c06e8853c900..0d34cdeaa66fd 100644 --- a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts +++ b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts @@ -30,7 +30,7 @@ import { sections, } from '@superset-ui/chart-controls'; -import cidrRegex from 'cidr-regex'; +//import cidrRegex from 'cidr-regex'; @@ -61,15 +61,6 @@ function isQueryMode(mode: QueryMode) { const isAggMode = isQueryMode(QueryMode.aggregate); const isRawMode = isQueryMode(QueryMode.raw); -function getDataSourceSql(controls: ControlStateMapping): QueryMode { - return controls?.datasource?.datasource?.sql; -} - -function datasourceAcceptsParam(paramType: string) { - return ({ controls }: ControlPanelsContainerProps) => getDataSourceSql(controls)?.includes(paramType); -} - -const datasourceAcceptsIpParam = datasourceAcceptsParam('_ipv4_parameter_'); const queryMode: ControlConfig<'RadioButtonControl'> = { @@ -93,7 +84,8 @@ const queryMode: ControlConfig<'RadioButtonControl'> = { - +/* +keep this code, we will use it in input validators once we know how to hook them into the ad-hoc filter function isIP(v: unknown) { if (typeof v === 'string' && v.trim().length > 0) { @@ -125,8 +117,7 @@ function validateIP(v: unknown) { return ('is expected to be an ip address or cidr'); } - - +*/ const config: ControlPanelConfig = { @@ -137,36 +128,14 @@ const config: ControlPanelConfig = { label: t('Query'), expanded: true, controlSetRows: [ - [ - { - name: '_ipv4_parameter_', - config: { - type: 'SelectControl', - label: t('IP Params'), - default: [], - multi: true, - allowClear: true, - freeForm: true, - allowAll: true, - tokenSeparators: [' ', ',', '\n', '\t', ';'], - validators: [validateIP], - renderTrigger: false, - description: t('The IPs or CIDRs to filter'), - visibility: datasourceAcceptsIpParam, - } - - }, - - ], - - [ - { - name: 'query_mode', - config: queryMode, - }, - ], + [ + { + name: 'query_mode', + config: queryMode, + }, + ], - [ + [ { name: 'metrics', override: { @@ -283,6 +252,12 @@ const config: ControlPanelConfig = { series: { validators: [validateNonEmpty], clearable: false, + }, + viz_type: { + default: 'hello_world' + }, + time_range: { + default: t('Last day'), }, row_limit: { default: 100, From 995de9bda4bce23b0abc2871387b01406df1fd30 Mon Sep 17 00:00:00 2001 From: cccs-jc Date: Mon, 15 Mar 2021 19:44:38 +0000 Subject: [PATCH 4/6] hooked in a adhoc filter validator --- .../src/plugin/controlPanel.ts | 79 +++++++++++++++---- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts index 0d34cdeaa66fd..cdc9b00d90df2 100644 --- a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts +++ b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts @@ -28,10 +28,11 @@ import { ControlPanelConfig, ControlPanelsContainerProps, sections, + ControlState, } from '@superset-ui/chart-controls'; -//import cidrRegex from 'cidr-regex'; +import cidrRegex from 'cidr-regex'; @@ -84,8 +85,6 @@ const queryMode: ControlConfig<'RadioButtonControl'> = { -/* -keep this code, we will use it in input validators once we know how to hook them into the ad-hoc filter function isIP(v: unknown) { if (typeof v === 'string' && v.trim().length > 0) { @@ -114,10 +113,51 @@ function validateIP(v: unknown) { } } - return ('is expected to be an ip address or cidr'); + return (' is expected to be an ip address or cidr'); +} + +// filters is an array of adhoc filter with the following attributes +// f.subject is the column name for example SRC_PORT +// f.comparator is the value being tested, it can be a single value for operators like !=, >, <= etc +// or it can be an array of values for example when the IN or NOT IN operator is used. +// state is the current state of the adhoc filter control it includes +// a copy of the columns as defined in the dataset model +function adhocFilterValidator(filters: unknown, state: ControlState) { + if (Array.isArray(filters)) { + for (let i = 0; i < filters.length; i++) { + const filter = filters[i]; + // Find the corresponding column in the model + const column = state.columns.find((c: any) => c.column_name == filter.subject); + if (typeof column !== 'undefined' && typeof column.type !== 'undefined') { + // Currently supporting 2 types of columns + // IPV4 + // IPV4 FILTER + if (column.type.includes('IPV4')) { + const v = filter.comparator; + // check single value + if (typeof v === 'string' && v.trim().length > 0) { + const error = validateIP(v.trim()); + if (error) { + return filter.subject + error; + } + } + // check array of values + else if (Array.isArray(v)) { + for (let index = 0; index < v.length; index++) { + const element = v[index]; + const error = validateIP(element.trim()); + if (error) { + return filter.subject + error; + } + } + } + } + } + } + } + return false; } -*/ const config: ControlPanelConfig = { @@ -128,14 +168,14 @@ const config: ControlPanelConfig = { label: t('Query'), expanded: true, controlSetRows: [ - [ - { - name: 'query_mode', - config: queryMode, - }, - ], + [ + { + name: 'query_mode', + config: queryMode, + }, + ], - [ + [ { name: 'metrics', override: { @@ -180,7 +220,14 @@ const config: ControlPanelConfig = { }, ], - ['adhoc_filters'], + [ + { + name: 'adhoc_filters', + override: { + validators: [adhocFilterValidator], + } + } + ], [ { name: 'row_limit', @@ -253,11 +300,11 @@ const config: ControlPanelConfig = { validators: [validateNonEmpty], clearable: false, }, - viz_type: { - default: 'hello_world' + viz_type: { + default: 'hello_world' }, time_range: { - default: t('Last day'), + default: t('Last day'), }, row_limit: { default: 100, From bdac73d642f254cd6a0e75fb2aea9864998d4476 Mon Sep 17 00:00:00 2001 From: cccs-jc Date: Tue, 16 Mar 2021 15:11:17 +0000 Subject: [PATCH 5/6] override of controls you list should not be done in controlOverrides section --- .../plugin-chart-hello-world/src/plugin/controlPanel.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts index cdc9b00d90df2..2a85510fb915f 100644 --- a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts +++ b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts @@ -295,6 +295,7 @@ const config: ControlPanelConfig = { }, ], + // override controls that are inherited by the default configuration controlOverrides: { series: { validators: [validateNonEmpty], @@ -306,9 +307,6 @@ const config: ControlPanelConfig = { time_range: { default: t('Last day'), }, - row_limit: { - default: 100, - }, }, }; From 9daa543a4fed24e8663a916ddfa7f462c06f834a Mon Sep 17 00:00:00 2001 From: cccs-jc Date: Tue, 16 Mar 2021 19:13:42 +0000 Subject: [PATCH 6/6] code review fixes --- .../src/plugin/controlPanel.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts index 2a85510fb915f..91c34de50d6c6 100644 --- a/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts +++ b/superset-frontend/cccs-viz/plugins/plugin-chart-hello-world/src/plugin/controlPanel.ts @@ -113,15 +113,18 @@ function validateIP(v: unknown) { } } - return (' is expected to be an ip address or cidr'); + return (' is expected to be an IP address in dotted decimal or CIDR notation'); } -// filters is an array of adhoc filter with the following attributes -// f.subject is the column name for example SRC_PORT -// f.comparator is the value being tested, it can be a single value for operators like !=, >, <= etc -// or it can be an array of values for example when the IN or NOT IN operator is used. -// state is the current state of the adhoc filter control it includes -// a copy of the columns as defined in the dataset model +/** + * Validates the adhoc filter control. Each filter has a subject (the column name for example SRC_PORT) and a comparator (the value being tested), + * it can be a single value for operators like !=, >, <= etc + * or it can be an array of values for example when the IN or NOT IN operator is used. + * + * @param filters an array of adhoc filter with the following attributes + * @param state the current state of the adhoc filter control it includes a copy of the columns as defined in the dataset model + * @returns a string explaining the reason why the control is in an invalid state or false if there is no errors + */ function adhocFilterValidator(filters: unknown, state: ControlState) { if (Array.isArray(filters)) { for (let i = 0; i < filters.length; i++) { @@ -152,6 +155,8 @@ function adhocFilterValidator(filters: unknown, state: ControlState) { } } } + // else we assume the value is okay + // more type validators can be added here } } }