This is an automated email from the ASF dual-hosted git repository.

diegopucci pushed a commit to branch feat/disable-controls-sections
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 36bccaba7008a42ed60798b9fa15c1bd93e97e59
Author: geido <[email protected]>
AuthorDate: Wed Dec 14 18:27:50 2022 +0100

    Implement ability to disable sections
---
 .../src/sections/advancedAnalytics.tsx             |  12 +-
 .../src/sections/forecastInterval.tsx              |   6 +
 .../superset-ui-chart-controls/src/types.ts        |   2 +
 .../utils/{index.ts => disabledSectionRules.ts}    |  35 +++-
 .../superset-ui-chart-controls/src/utils/index.ts  |   1 +
 .../test/utils/disabledSectionRules.test.ts        |  75 ++++++++
 .../components/ControlPanelSection.test.tsx        |  91 +++++++++
 .../src/explore/components/ControlPanelSection.tsx | 206 +++++++++++++++++++++
 .../explore/components/ControlPanelsContainer.tsx  | 134 +++-----------
 9 files changed, 444 insertions(+), 118 deletions(-)

diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/src/sections/advancedAnalytics.tsx
 
b/superset-frontend/packages/superset-ui-chart-controls/src/sections/advancedAnalytics.tsx
index c67018f1fe..eeb3e9a8da 100644
--- 
a/superset-frontend/packages/superset-ui-chart-controls/src/sections/advancedAnalytics.tsx
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/src/sections/advancedAnalytics.tsx
@@ -19,7 +19,11 @@
 import React from 'react';
 import { t, RollingType, ComparisionType } from '@superset-ui/core';
 import { ControlPanelSectionConfig } from '../types';
-import { formatSelectOptions } from '../utils';
+import {
+  formatSelectOptions,
+  isSectionDisabled,
+  SectionRuleType,
+} from '../utils';
 
 export const advancedAnalyticsControls: ControlPanelSectionConfig = {
   label: t('Advanced analytics'),
@@ -195,4 +199,10 @@ export const advancedAnalyticsControls: 
ControlPanelSectionConfig = {
       },
     ],
   ],
+  expanded: false,
+  setDisabled: ({ exploreState }) =>
+    isSectionDisabled(SectionRuleType.X_AXIS_TEMPORAL, exploreState),
+  disabledTooltipText: t(
+    'These controls are only available if a temporal x-axis is selected',
+  ),
 };
diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/src/sections/forecastInterval.tsx
 
b/superset-frontend/packages/superset-ui-chart-controls/src/sections/forecastInterval.tsx
index 1dff19b83c..23715cbcb0 100644
--- 
a/superset-frontend/packages/superset-ui-chart-controls/src/sections/forecastInterval.tsx
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/src/sections/forecastInterval.tsx
@@ -22,6 +22,7 @@ import {
   t,
 } from '@superset-ui/core';
 import { ControlPanelSectionConfig } from '../types';
+import { isSectionDisabled, SectionRuleType } from '../utils';
 
 export const FORECAST_DEFAULT_DATA = {
   forecastEnabled: false,
@@ -134,4 +135,9 @@ export const forecastIntervalControls: 
ControlPanelSectionConfig = {
       },
     ],
   ],
+  setDisabled: ({ exploreState }) =>
+    isSectionDisabled(SectionRuleType.X_AXIS_TEMPORAL, exploreState),
+  disabledTooltipText: t(
+    'These controls are only available if a temporal x-axis is selected',
+  ),
 };
diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts 
b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
index 60cda2ede8..9c279ea7d1 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
+++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
@@ -370,6 +370,8 @@ export interface ControlPanelSectionConfig {
   expanded?: boolean;
   tabOverride?: TabOverride;
   controlSetRows: ControlSetRow[];
+  setDisabled?: (props: ControlPanelsContainerProps) => boolean;
+  disabledTooltipText?: string;
 }
 
 export interface StandardizedControls {
diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts 
b/superset-frontend/packages/superset-ui-chart-controls/src/utils/disabledSectionRules.ts
similarity index 51%
copy from 
superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts
copy to 
superset-frontend/packages/superset-ui-chart-controls/src/utils/disabledSectionRules.ts
index 4fa4243c1e..fb9ae54aa0 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/src/utils/disabledSectionRules.ts
@@ -16,12 +16,29 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-export * from './selectOptions';
-export * from './D3Formatting';
-export * from './expandControlConfig';
-export * from './getColorFormatters';
-export { default as mainMetric } from './mainMetric';
-export { default as columnChoices } from './columnChoices';
-export * from './defineSavedMetrics';
-export * from './getStandardizedControls';
-export * from './getTemporalColumns';
+
+import { ensureIsArray, GenericDataType } from '@superset-ui/core';
+
+export enum SectionRuleType {
+  X_AXIS_TEMPORAL = 'XAxisTemporal',
+}
+
+export function isSectionDisabled(rule: SectionRuleType, exploreState: any) {
+  switch (rule) {
+    case SectionRuleType.X_AXIS_TEMPORAL: {
+      if (exploreState?.form_data?.x_axis) {
+        const { datasource, form_data } = exploreState;
+        const xAxis = ensureIsArray(form_data?.x_axis)[0];
+        const column = ensureIsArray(datasource.columns).find(
+          (col: { column_name: string }) => col?.column_name === xAxis,
+        );
+        if (column?.type_generic !== GenericDataType.TEMPORAL) {
+          return true;
+        }
+      }
+      return false;
+    }
+    default:
+      return false;
+  }
+}
diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts 
b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts
index 4fa4243c1e..e7fb232ef0 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts
+++ b/superset-frontend/packages/superset-ui-chart-controls/src/utils/index.ts
@@ -25,3 +25,4 @@ export { default as columnChoices } from './columnChoices';
 export * from './defineSavedMetrics';
 export * from './getStandardizedControls';
 export * from './getTemporalColumns';
+export * from './disabledSectionRules';
diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/test/utils/disabledSectionRules.test.ts
 
b/superset-frontend/packages/superset-ui-chart-controls/test/utils/disabledSectionRules.test.ts
new file mode 100644
index 0000000000..b3369a49d0
--- /dev/null
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/test/utils/disabledSectionRules.test.ts
@@ -0,0 +1,75 @@
+/**
+ * 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 { GenericDataType } from '@superset-ui/core';
+import { isSectionDisabled, SectionRuleType } from '../../src';
+
+const nonTemporal = {
+  datasource: {
+    columns: [
+      {
+        column_name: 'test',
+        type_generic: GenericDataType.NUMERIC,
+      },
+    ],
+  },
+  form_data: {
+    x_axis: 'test',
+  },
+};
+
+const temporal = {
+  datasource: {
+    columns: [
+      {
+        column_name: 'test',
+        type_generic: GenericDataType.TEMPORAL,
+      },
+    ],
+  },
+  form_data: {
+    x_axis: 'test',
+  },
+};
+
+test('disables the section when X axis is not temporal', () => {
+  expect(
+    isSectionDisabled(SectionRuleType.X_AXIS_TEMPORAL, nonTemporal),
+  ).toEqual(true);
+});
+
+test('enables the section when X axis is not temporal', () => {
+  expect(isSectionDisabled(SectionRuleType.X_AXIS_TEMPORAL, temporal)).toEqual(
+    false,
+  );
+});
+
+test('enables the section when X axis is not available', () => {
+  expect(
+    isSectionDisabled(SectionRuleType.X_AXIS_TEMPORAL, {
+      ...nonTemporal,
+      form_data: {},
+    }),
+  ).toEqual(false);
+});
+
+test('shows by default', () => {
+  // @ts-ignore
+  expect(isSectionDisabled(undefined, temporal)).toEqual(false);
+});
diff --git 
a/superset-frontend/src/explore/components/ControlPanelSection.test.tsx 
b/superset-frontend/src/explore/components/ControlPanelSection.test.tsx
new file mode 100644
index 0000000000..32c4dae61c
--- /dev/null
+++ b/superset-frontend/src/explore/components/ControlPanelSection.test.tsx
@@ -0,0 +1,91 @@
+/**
+ * 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 { promiseTimeout } from '@superset-ui/core';
+import React from 'react';
+import { render, screen } from 'spec/helpers/testing-library';
+import Collapse from 'src/components/Collapse';
+import { ControlPanelSection } from './ControlPanelSection';
+
+const defaultProps = {
+  sectionId: 'query',
+  hasErrors: false,
+  errorColor: '#E04355',
+  section: {
+    label: 'mock section',
+    controlSetRows: [],
+  },
+  isVisible: true,
+  renderControl: jest.fn(),
+  actions: {
+    setControlValue: jest.fn(),
+  },
+};
+
+const setup = (overrides = {}) => (
+  <Collapse defaultActiveKey={['query']}>
+    <ControlPanelSection {...defaultProps} {...overrides} />
+  </Collapse>
+);
+
+it('should render component', () => {
+  render(setup());
+  expect(screen.getByText('mock section')).toBeInTheDocument();
+});
+
+it('should render as disabled if isDisabled is true', () => {
+  render(
+    setup({
+      isDisabled: true,
+      section: {
+        ...defaultProps.section,
+        disabledTooltipText: 'Test tooltip',
+      },
+    }),
+  );
+  expect(screen.getByTestId('disabled-section-tooltip')).toBeInTheDocument();
+});
+
+it('should call renderControl properly', () => {
+  render(
+    setup({
+      section: {
+        label: 'mock section',
+        controlSetRows: [
+          [null],
+          [<div />],
+          [{ name: 'control', config: { type: 'CheckboxControl' } }],
+          [{ name: 'datasource', config: {} }],
+        ],
+      },
+    }),
+  );
+  expect(defaultProps.renderControl).toBeCalledTimes(1);
+});
+
+it('should call setControlValue if isDisabled is false', () => {
+  render(
+    setup({
+      isDisabled: false,
+    }),
+  );
+
+  promiseTimeout(() => {
+    expect(defaultProps.actions.setControlValue).toBeCalled();
+  }, 100);
+});
diff --git a/superset-frontend/src/explore/components/ControlPanelSection.tsx 
b/superset-frontend/src/explore/components/ControlPanelSection.tsx
new file mode 100644
index 0000000000..b0e9bc9812
--- /dev/null
+++ b/superset-frontend/src/explore/components/ControlPanelSection.tsx
@@ -0,0 +1,206 @@
+/**
+ * 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, { useCallback, useEffect } from 'react';
+import {
+  ControlPanelSectionConfig,
+  CustomControlItem,
+  ExpandedControlItem,
+} from '@superset-ui/chart-controls';
+import { ensureIsArray, SupersetTheme, t, css } from '@superset-ui/core';
+import Collapse from 'src/components/Collapse';
+import { Tooltip } from 'src/components/Tooltip';
+import { kebabCase } from 'lodash';
+import Icons from 'src/components/Icons';
+import { usePrevious } from 'src/hooks/usePrevious';
+import { ExploreActions } from 'src/explore/actions/exploreActions';
+import ControlRow from './ControlRow';
+
+export type ExpandedControlPanelSectionConfig = Omit<
+  ControlPanelSectionConfig,
+  'controlSetRows'
+> & {
+  controlSetRows: ExpandedControlItem[][];
+};
+
+export const iconStyles = css`
+  &.anticon {
+    font-size: unset;
+    .anticon {
+      line-height: unset;
+      vertical-align: unset;
+    }
+  }
+`;
+
+type IControlPanelSectionProps = {
+  actions: Partial<ExploreActions> & Pick<ExploreActions, 'setControlValue'>;
+  sectionId: string;
+  section: ExpandedControlPanelSectionConfig;
+  hasErrors: boolean;
+  errorColor: string;
+  renderControl: (item: CustomControlItem) => JSX.Element;
+  isDisabled?: boolean;
+};
+
+export function ControlPanelSection({
+  actions: { setControlValue },
+  sectionId,
+  section,
+  hasErrors,
+  errorColor,
+  renderControl,
+  isDisabled,
+  ...restProps // 
https://github.com/react-component/collapse/issues/73#issuecomment-323626120
+}: IControlPanelSectionProps) {
+  const { label, description, disabledTooltipText } = section;
+  const wasDisabled = usePrevious(isDisabled);
+  const clearDisabledSectionControls = useCallback(() => {
+    ensureIsArray(section.controlSetRows).forEach(controlSets => {
+      controlSets.forEach(controlItem => {
+        if (
+          controlItem &&
+          !React.isValidElement(controlItem) &&
+          controlItem.name &&
+          controlItem.config &&
+          controlItem.name !== 'datasource'
+        ) {
+          setControlValue?.(controlItem.name, controlItem.config.default);
+        }
+      });
+    });
+  }, [setControlValue, section]);
+
+  useEffect(() => {
+    if (wasDisabled === false && isDisabled) {
+      clearDisabledSectionControls();
+    }
+  }, [wasDisabled, isDisabled]);
+
+  const PanelHeader = () => (
+    <span data-test="collapsible-control-panel-header">
+      <span
+        css={(theme: SupersetTheme) => css`
+          font-size: ${theme.typography.sizes.m}px;
+          line-height: 1.3;
+        `}
+      >
+        {label}
+      </span>{' '}
+      {!isDisabled && description && (
+        <Tooltip id={sectionId} title={description}>
+          <Icons.InfoCircleOutlined css={iconStyles} />
+        </Tooltip>
+      )}
+      {!isDisabled && hasErrors && (
+        <Tooltip
+          id={`${kebabCase('validation-errors')}-tooltip`}
+          title={t('This section contains validation errors')}
+        >
+          <Icons.InfoCircleOutlined
+            css={css`
+              ${iconStyles};
+              color: ${errorColor};
+            `}
+          />
+        </Tooltip>
+      )}
+      {isDisabled && disabledTooltipText && (
+        <Tooltip
+          id={`${kebabCase('disabled-section')}-tooltip`}
+          title={disabledTooltipText}
+        >
+          <Icons.InfoCircleOutlined
+            data-test="disabled-section-tooltip"
+            css={css`
+              ${iconStyles};
+            `}
+          />
+        </Tooltip>
+      )}
+    </span>
+  );
+
+  return (
+    <Collapse.Panel
+      {...restProps}
+      collapsible={isDisabled ? 'disabled' : undefined}
+      showArrow={!isDisabled}
+      css={theme => css`
+        margin-bottom: 0;
+        box-shadow: none;
+
+        &:last-child {
+          padding-bottom: ${theme.gridUnit * 16}px;
+          border-bottom: 0;
+        }
+
+        .panel-body {
+          margin-left: ${theme.gridUnit * 4}px;
+          padding-bottom: 0;
+        }
+
+        span.label {
+          display: inline-block;
+        }
+        ${!section.label &&
+        `
+             .ant-collapse-header {
+               display: none;
+             }
+           `}
+      `}
+      header={<PanelHeader />}
+      key={sectionId}
+    >
+      {!isDisabled &&
+        section.controlSetRows.map((controlSets, i) => {
+          const renderedControls = controlSets
+            .map(controlItem => {
+              if (!controlItem) {
+                // When the item is invalid
+                return null;
+              }
+              if (React.isValidElement(controlItem)) {
+                // When the item is a React element
+                return controlItem;
+              }
+              if (
+                controlItem.name &&
+                controlItem.config &&
+                controlItem.name !== 'datasource'
+              ) {
+                return renderControl(controlItem);
+              }
+              return null;
+            })
+            .filter(x => x !== null);
+          // don't show the row if it is empty
+          if (renderedControls.length === 0) {
+            return null;
+          }
+          return (
+            <ControlRow
+              key={`controlsetrow-${i}`}
+              controls={renderedControls}
+            />
+          );
+        })}
+    </Collapse.Panel>
+  );
+}
diff --git 
a/superset-frontend/src/explore/components/ControlPanelsContainer.tsx 
b/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
index 7b0ffeb3b6..a638389943 100644
--- a/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
+++ b/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
@@ -49,7 +49,6 @@ import {
 } from '@superset-ui/chart-controls';
 import { useSelector } from 'react-redux';
 import { rgba } from 'emotion-rgba';
-import { kebabCase } from 'lodash';
 
 import Collapse from 'src/components/Collapse';
 import Tabs from 'src/components/Tabs';
@@ -62,10 +61,10 @@ import { ExploreActions } from 
'src/explore/actions/exploreActions';
 import { ChartState, ExplorePageState } from 'src/explore/types';
 import { Tooltip } from 'src/components/Tooltip';
 import Icons from 'src/components/Icons';
-import ControlRow from './ControlRow';
 import Control from './Control';
 import { ExploreAlert } from './ExploreAlert';
 import { RunQueryButton } from './RunQueryButton';
+import { ControlPanelSection } from './ControlPanelSection';
 
 export type ControlPanelsContainerProps = {
   exploreState: ExplorePageState['explore'];
@@ -191,21 +190,21 @@ const hasTimeColumn = (datasource: Dataset): boolean =>
   datasource?.columns?.some(c => c.is_dttm);
 const sectionsToExpand = (
   sections: ControlPanelSectionConfig[],
-  datasource: Dataset,
+  exploreState: ExplorePageState['explore'],
 ): string[] =>
   // avoid expanding time section if datasource doesn't include time column
-  sections.reduce(
-    (acc, section) =>
-      (section.expanded || !section.label) &&
-      (!isTimeSection(section) || hasTimeColumn(datasource))
-        ? [...acc, String(section.label)]
-        : acc,
-    [] as string[],
-  );
+  sections.reduce((acc, section) => {
+    const isDisabled = section?.setDisabled?.call(section, exploreState);
+    const shouldExpand = isDisabled
+      ? false
+      : (section.expanded || !section.label) &&
+        (!isTimeSection(section) || hasTimeColumn(exploreState.datasource));
+    return shouldExpand ? [...acc, String(section.label)] : acc;
+  }, [] as string[]);
 
 function getState(
   vizType: string,
-  datasource: Dataset,
+  exploreState: ExplorePageState['explore'],
   datasourceType: DatasourceType,
 ) {
   const querySections: ControlPanelSectionConfig[] = [];
@@ -235,11 +234,11 @@ function getState(
   });
   const expandedQuerySections: string[] = sectionsToExpand(
     querySections,
-    datasource,
+    exploreState,
   );
   const expandedCustomizeSections: string[] = sectionsToExpand(
     customizeSections,
-    datasource,
+    exploreState,
   );
   return {
     expandedQuerySections,
@@ -347,7 +346,7 @@ export const ControlPanelsContainer = (props: 
ControlPanelsContainerProps) => {
     () =>
       getState(
         props.form_data.viz_type,
-        props.exploreState.datasource,
+        props.exploreState,
         props.datasource_type,
       ),
     [
@@ -453,8 +452,9 @@ export const ControlPanelsContainer = (props: 
ControlPanelsContainerProps) => {
   const renderControlPanelSection = (
     section: ExpandedControlPanelSectionConfig,
   ) => {
-    const { controls } = props;
-    const { label, description } = section;
+    const { label, setDisabled } = section;
+    const { controls, actions } = props;
+    const isDisabled = setDisabled ? setDisabled.call(section, props) : false;
 
     // Section label can be a ReactNode but in some places we want to
     // have a string ID. Using forced type conversion for now,
@@ -486,99 +486,17 @@ export const ControlPanelsContainer = (props: 
ControlPanelsContainerProps) => {
       ? colors.error.base
       : colors.alert.base;
 
-    const PanelHeader = () => (
-      <span data-test="collapsible-control-panel-header">
-        <span
-          css={(theme: SupersetTheme) => css`
-            font-size: ${theme.typography.sizes.m}px;
-            line-height: 1.3;
-          `}
-        >
-          {label}
-        </span>{' '}
-        {description && (
-          <Tooltip id={sectionId} title={description}>
-            <Icons.InfoCircleOutlined css={iconStyles} />
-          </Tooltip>
-        )}
-        {hasErrors && (
-          <Tooltip
-            id={`${kebabCase('validation-errors')}-tooltip`}
-            title={t('This section contains validation errors')}
-          >
-            <Icons.InfoCircleOutlined
-              css={css`
-                ${iconStyles};
-                color: ${errorColor};
-              `}
-            />
-          </Tooltip>
-        )}
-      </span>
-    );
-
     return (
-      <Collapse.Panel
-        css={theme => css`
-          margin-bottom: 0;
-          box-shadow: none;
-
-          &:last-child {
-            padding-bottom: ${theme.gridUnit * 16}px;
-            border-bottom: 0;
-          }
-
-          .panel-body {
-            margin-left: ${theme.gridUnit * 4}px;
-            padding-bottom: 0;
-          }
-
-          span.label {
-            display: inline-block;
-          }
-          ${!section.label &&
-          `
-            .ant-collapse-header {
-              display: none;
-            }
-          `}
-        `}
-        header={<PanelHeader />}
+      <ControlPanelSection
         key={sectionId}
-      >
-        {section.controlSetRows.map((controlSets, i) => {
-          const renderedControls = controlSets
-            .map(controlItem => {
-              if (!controlItem) {
-                // When the item is invalid
-                return null;
-              }
-              if (React.isValidElement(controlItem)) {
-                // When the item is a React element
-                return controlItem;
-              }
-              if (
-                controlItem.name &&
-                controlItem.config &&
-                controlItem.name !== 'datasource'
-              ) {
-                return renderControl(controlItem);
-              }
-              return null;
-            })
-            .filter(x => x !== null);
-          // don't show the row if it is empty
-          if (renderedControls.length === 0) {
-            return null;
-          }
-          return (
-            <ControlRow
-              key={`controlsetrow-${i}`}
-              controls={renderedControls}
-            />
-          );
-        })}
-      </Collapse.Panel>
+        sectionId={sectionId}
+        actions={actions}
+        section={section}
+        hasErrors={hasErrors}
+        errorColor={errorColor}
+        isDisabled={isDisabled}
+        renderControl={renderControl}
+      />
     );
   };
 

Reply via email to