This is an automated email from the ASF dual-hosted git repository. suddjian pushed a commit to branch dynamic-plugin-import in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
commit 42f97e728ffaeafebfc352288bb204b3fc58e40e Author: David Aaron Suddjian <[email protected]> AuthorDate: Fri Jul 10 13:56:47 2020 -0700 more work on making it work, + feature flag --- .../src/components/AlteredSliceTag.jsx | 25 ++++++---------- .../DynamicPlugins/DynamicPluginProvider.tsx | 8 +++-- .../explore/components/ControlPanelsContainer.jsx | 4 +-- superset-frontend/src/featureFlags.ts | 1 + .../src/utils/getControlsForVizType.js | 35 ++++++++++++---------- superset/app.py | 17 ++++++----- superset/config.py | 1 + 7 files changed, 47 insertions(+), 44 deletions(-) diff --git a/superset-frontend/src/components/AlteredSliceTag.jsx b/superset-frontend/src/components/AlteredSliceTag.jsx index d158461..509d0f1 100644 --- a/superset-frontend/src/components/AlteredSliceTag.jsx +++ b/superset-frontend/src/components/AlteredSliceTag.jsx @@ -53,9 +53,7 @@ export default class AlteredSliceTag extends React.Component { super(props); const diffs = this.getDiffs(props); - const controlsMap = getControlsForVizType(this.props.origFormData.viz_type); - - this.state = { diffs, hasDiffs: !isEmpty(diffs), controlsMap }; + this.state = { diffs, hasDiffs: !isEmpty(diffs) }; } UNSAFE_componentWillReceiveProps(newProps) { @@ -96,6 +94,7 @@ export default class AlteredSliceTag extends React.Component { } formatValue(value, key) { + const controlsMap = getControlsForVizType(this.props.origFormData.viz_type); // Format display value based on the control type // or the value type if (value === undefined) { @@ -103,8 +102,8 @@ export default class AlteredSliceTag extends React.Component { } else if (value === null) { return 'null'; } else if ( - this.state.controlsMap[key] && - this.state.controlsMap[key].type === 'AdhocFilterControl' + controlsMap[key] && + controlsMap[key].type === 'AdhocFilterControl' ) { if (!value.length) { return '[]'; @@ -118,14 +117,11 @@ export default class AlteredSliceTag extends React.Component { return `${v.subject} ${v.operator} ${filterVal}`; }) .join(', '); - } else if ( - this.state.controlsMap[key] && - this.state.controlsMap[key].type === 'BoundsControl' - ) { + } else if (controlsMap[key] && controlsMap[key].type === 'BoundsControl') { return `Min: ${value[0]}, Max: ${value[1]}`; } else if ( - this.state.controlsMap[key] && - this.state.controlsMap[key].type === 'CollectionControl' + controlsMap[key] && + controlsMap[key].type === 'CollectionControl' ) { return value.map(v => safeStringify(v)).join(', '); } else if (typeof value === 'boolean') { @@ -139,6 +135,7 @@ export default class AlteredSliceTag extends React.Component { } renderRows() { + const controlsMap = getControlsForVizType(this.props.origFormData.viz_type); const diffs = this.state.diffs; const rows = []; for (const key in diffs) { @@ -146,11 +143,7 @@ export default class AlteredSliceTag extends React.Component { <Tr key={key}> <Td column="control" - data={ - (this.state.controlsMap[key] && - this.state.controlsMap[key].label) || - key - } + data={(controlsMap[key] && controlsMap[key].label) || key} /> <Td column="before">{this.formatValue(diffs[key].before, key)}</Td> <Td column="after">{this.formatValue(diffs[key].after, key)}</Td> diff --git a/superset-frontend/src/components/DynamicPlugins/DynamicPluginProvider.tsx b/superset-frontend/src/components/DynamicPlugins/DynamicPluginProvider.tsx index b14f4bd..476c1f9 100644 --- a/superset-frontend/src/components/DynamicPlugins/DynamicPluginProvider.tsx +++ b/superset-frontend/src/components/DynamicPlugins/DynamicPluginProvider.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useReducer } from 'react'; import { SupersetClient, Json } from '@superset-ui/connection'; +import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags'; import { PluginContext, PluginContextType, @@ -96,6 +97,7 @@ export default function DynamicPluginProvider({ children }: Props) { ...dummyPluginContext, // eslint-disable-next-line @typescript-eslint/no-use-before-define fetchAll, + loading: isFeatureEnabled(FeatureFlag.DYNAMIC_PLUGINS), // TODO: Write fetchByKeys }); @@ -130,7 +132,7 @@ export default function DynamicPluginProvider({ children }: Props) { // eslint-disable-next-line no-console console.error( `Failed to load plugin ${plugin.key} with the following error:`, - err, + err.stack, ); error = err; } @@ -148,7 +150,9 @@ export default function DynamicPluginProvider({ children }: Props) { } useEffect(() => { - fetchAll(); + if (isFeatureEnabled(FeatureFlag.DYNAMIC_PLUGINS)) { + fetchAll(); + } }, []); return ( diff --git a/superset-frontend/src/explore/components/ControlPanelsContainer.jsx b/superset-frontend/src/explore/components/ControlPanelsContainer.jsx index 6d610e4..2cd3269 100644 --- a/superset-frontend/src/explore/components/ControlPanelsContainer.jsx +++ b/superset-frontend/src/explore/components/ControlPanelsContainer.jsx @@ -171,9 +171,9 @@ class ControlPanelsContainer extends React.Component { } render() { - const cpRegistry = getChartControlPanelRegistry(); + const controlPanelRegistry = getChartControlPanelRegistry(); if ( - !cpRegistry.has(this.props.form_data.viz_type) && + !controlPanelRegistry.has(this.props.form_data.viz_type) && this.context.loading ) { // TODO replace with a snazzy loading spinner diff --git a/superset-frontend/src/featureFlags.ts b/superset-frontend/src/featureFlags.ts index 0853578..8cb177a 100644 --- a/superset-frontend/src/featureFlags.ts +++ b/superset-frontend/src/featureFlags.ts @@ -26,6 +26,7 @@ export enum FeatureFlag { ESTIMATE_QUERY_COST = 'ESTIMATE_QUERY_COST', SHARE_QUERIES_VIA_KV_STORE = 'SHARE_QUERIES_VIA_KV_STORE', SQLLAB_BACKEND_PERSISTENCE = 'SQLLAB_BACKEND_PERSISTENCE', + DYNAMIC_PLUGINS = 'DYNAMIC_PLUGINS', } export type FeatureFlagMap = { diff --git a/superset-frontend/src/utils/getControlsForVizType.js b/superset-frontend/src/utils/getControlsForVizType.js index 3be5b7e..fd0abc1 100644 --- a/superset-frontend/src/utils/getControlsForVizType.js +++ b/superset-frontend/src/utils/getControlsForVizType.js @@ -21,26 +21,29 @@ import memoize from 'lodash/memoize'; import { getChartControlPanelRegistry } from '@superset-ui/chart'; import controls from '../explore/controls'; -const getControlsForVizType = memoize(vizType => { +const memoizedControls = memoize((vizType, controlPanel) => { const controlsMap = {}; - getChartControlPanelRegistry() - .get(vizType) - .controlPanelSections.forEach(section => { - section.controlSetRows.forEach(row => { - row.forEach(control => { - if (!control) return; - if (typeof control === 'string') { - // For now, we have to look in controls.jsx to get the config for some controls. - // Once everything is migrated out, delete this if statement. - controlsMap[control] = controls[control]; - } else if (control.name && control.config) { - // condition needed because there are elements, e.g. <hr /> in some control configs (I'm looking at you, FilterBox!) - controlsMap[control.name] = control.config; - } - }); + controlPanel.controlPanelSections.forEach(section => { + section.controlSetRows.forEach(row => { + row.forEach(control => { + if (!control) return; + if (typeof control === 'string') { + // For now, we have to look in controls.jsx to get the config for some controls. + // Once everything is migrated out, delete this if statement. + controlsMap[control] = controls[control]; + } else if (control.name && control.config) { + // condition needed because there are elements, e.g. <hr /> in some control configs (I'm looking at you, FilterBox!) + controlsMap[control.name] = control.config; + } }); }); + }); return controlsMap; }); +const getControlsForVizType = vizType => { + const controlPanel = getChartControlPanelRegistry().get(vizType); + return memoizedControls(vizType, controlPanel); +}; + export default getControlsForVizType; diff --git a/superset/app.py b/superset/app.py index 5800001..295cd1a 100644 --- a/superset/app.py +++ b/superset/app.py @@ -239,14 +239,15 @@ class SupersetAppInitializer: category="", category_icon="", ) - appbuilder.add_view( - DynamicPluginsView, - "Custom Plugins", - label=__("Custom Plugins"), - category="Manage", - category_label=__("Manage"), - icon="fa-puzzle-piece", - ) + if feature_flag_manager.is_feature_enabled("DYNAMIC_PLUGINS"): + appbuilder.add_view( + DynamicPluginsView, + "Custom Plugins", + label=__("Custom Plugins"), + category="Manage", + category_label=__("Manage"), + icon="fa-puzzle-piece", + ) appbuilder.add_view( CssTemplateModelView, "CSS Templates", diff --git a/superset/config.py b/superset/config.py index cfef8c2..bcce955 100644 --- a/superset/config.py +++ b/superset/config.py @@ -308,6 +308,7 @@ DEFAULT_FEATURE_FLAGS: Dict[str, bool] = { "SIP_38_VIZ_REARCHITECTURE": False, "TAGGING_SYSTEM": False, "SQLLAB_BACKEND_PERSISTENCE": False, + "DYNAMIC_PLUGINS": False, } # This is merely a default.
