export function LayerPanel()

in x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx [45:879]


export function LayerPanel(props: LayerPanelProps) {
  const [openDimension, setOpenDimension] = useState<{
    isComplete?: boolean;
    openColumnId?: string;
    openColumnGroup?: VisualizationDimensionGroupConfig;
  }>({});

  const [isPanelSettingsOpen, setPanelSettingsOpen] = useState(false);
  const { euiTheme } = useEuiTheme();

  const {
    framePublicAPI,
    layerId,
    isOnlyLayer,
    dimensionGroups,
    onRemoveLayer,
    onCloneLayer,
    registerNewLayerRef,
    layerIndex,
    activeVisualization,
    visualizationMap,
    datasourceMap,
    updateVisualization,
    updateDatasource,
    toggleFullscreen,
    updateAll,
    updateDatasourceAsync,
    visualizationState,
    onChangeIndexPattern,
    core,
    onDropToDimension,
    setIsInlineFlyoutVisible,
    onlyAllowSwitchToSubtypes,
    ...editorProps
  } = props;

  const isInlineEditing = Boolean(props?.setIsInlineFlyoutVisible);

  const isSaveable = useLensSelector((state) => state.lens.isSaveable);

  const datasourceStates = useLensSelector(selectDatasourceStates);
  const isFullscreen = useLensSelector(selectIsFullscreenDatasource);
  const dateRange = useLensSelector(selectResolvedDateRange);

  useEffect(() => {
    // is undefined when the dimension panel is closed
    setIsInlineFlyoutVisible?.(!openDimension.openColumnId);
  }, [openDimension.openColumnId, setIsInlineFlyoutVisible]);

  const panelRef = useRef<HTMLDivElement | null>(null);
  const settingsPanelRef = useRef<HTMLDivElement | null>(null);

  const registerLayerRef = useCallback(
    (el: HTMLDivElement | null) => registerNewLayerRef(layerId, el),
    [layerId, registerNewLayerRef]
  );

  const closeDimensionEditor = () => {
    if (layerDatasource) {
      if (layerDatasource.updateStateOnCloseDimension) {
        const newState = layerDatasource.updateStateOnCloseDimension({
          state: layerDatasourceState,
          layerId,
          columnId: openColumnId!,
        });
        if (newState) {
          props.updateDatasource(datasourceId, newState);
        }
      }
    }

    setOpenDimension({});
    if (isFullscreen) {
      toggleFullscreen();
    }
  };

  const layerVisualizationConfigProps = {
    layerId,
    state: props.visualizationState,
    frame: props.framePublicAPI,
    dateRange,
    activeData: props.framePublicAPI.activeData,
  };

  const datasourcePublicAPI = framePublicAPI.datasourceLayers?.[layerId];
  const datasourceId = datasourcePublicAPI?.datasourceId! as 'formBased' | 'textBased';
  let layerDatasourceState = datasourceStates?.[datasourceId]?.state;
  // try again with aliases
  if (!layerDatasourceState && datasourcePublicAPI?.datasourceAliasIds && datasourceStates) {
    const aliasId = datasourcePublicAPI.datasourceAliasIds.find(
      (id) => datasourceStates?.[id]?.state
    );
    if (aliasId) {
      layerDatasourceState = datasourceStates[aliasId].state;
    }
  }
  const layerDatasource = datasourceId ? props.datasourceMap[datasourceId] : undefined;

  const layerDatasourceConfigProps = {
    state: layerDatasourceState,
    setState: (newState: unknown) => {
      updateDatasource(datasourceId, newState);
    },
    layerId,
    frame: props.framePublicAPI,
    dateRange,
  };

  const columnLabelMap =
    !layerDatasource && activeVisualization.getUniqueLabels
      ? activeVisualization.getUniqueLabels(props.visualizationState)
      : layerDatasource?.uniqueLabels?.(
          layerDatasourceConfigProps?.state,
          framePublicAPI.dataViews.indexPatterns
        );

  const isEmptyLayer = !dimensionGroups.some((d) => d.accessors.length > 0);
  const { openColumnId, openColumnGroup, isComplete } = openDimension;

  useEffect(() => {
    if (!openColumnId) {
      return;
    }

    const derivedOpenColumnGroup = dimensionGroups.find((group) =>
      group.accessors.some((a) => a.columnId === openColumnId)
    );
    // dont update if nothing has changed
    if (
      isComplete === !!derivedOpenColumnGroup &&
      derivedOpenColumnGroup?.groupId === openColumnGroup?.groupId
    ) {
      return;
    }
    if (derivedOpenColumnGroup) {
      // if column is found, mark it as complete. If it's moved to another group, update the group
      setOpenDimension({
        openColumnId,
        openColumnGroup: derivedOpenColumnGroup,
        isComplete: !!derivedOpenColumnGroup,
      });
    }
    // if column is not found but is not new (is complete), close the dimension panel
    if (isComplete && !derivedOpenColumnGroup) {
      setOpenDimension({});
    }
  }, [openColumnId, dimensionGroups, isComplete, openColumnGroup?.groupId]);

  const allAccessors = dimensionGroups.flatMap((group) =>
    group.accessors.map((accessor) => accessor.columnId)
  );

  const {
    setNextFocusedId: setNextFocusedButtonId,
    removeRef: removeButtonRef,
    registerNewRef: registerNewButtonRef,
  } = useFocusUpdate(allAccessors);

  const onDrop = useCallback(
    (source: DragDropIdentifier, target: DragDropIdentifier, dropType?: DropType) => {
      if (!dropType) {
        return;
      }
      if (!isOperation(target)) {
        throw new Error('Drop target should be an operation');
      }

      if (dropType === 'reorder' || dropType === 'field_replace' || dropType === 'field_add') {
        setNextFocusedButtonId(source.id);
      } else {
        setNextFocusedButtonId(target.columnId);
      }

      onDropToDimension({ source, target, dropType });
    },
    [setNextFocusedButtonId, onDropToDimension]
  );

  const isDimensionPanelOpen = Boolean(openColumnId);

  const updateDataLayerState = useCallback(
    (
      newState: unknown,
      {
        isDimensionComplete = true,
        // this flag is a hack to force a sync render where it was planned an async/setTimeout state update
        // TODO: revisit this once we get rid of updateDatasourceAsync upstream
        forceRender = false,
      }: { isDimensionComplete?: boolean; forceRender?: boolean } = {}
    ) => {
      if (!openColumnGroup || !openColumnId) {
        return;
      }
      if (allAccessors.includes(openColumnId)) {
        if (isDimensionComplete) {
          if (forceRender) {
            updateDatasource(datasourceId, newState);
          } else {
            updateDatasourceAsync(datasourceId, newState);
          }
        } else {
          // The datasource can indicate that the previously-valid column is no longer
          // complete, which clears the visualization. This keeps the flyout open and reuses
          // the previous columnId
          props.updateDatasource(datasourceId, newState);
          props.onRemoveDimension({ layerId, columnId: openColumnId });
        }
      } else if (isDimensionComplete) {
        updateAll(
          datasourceId,
          newState,
          activeVisualization.setDimension({
            layerId,
            groupId: openColumnGroup.groupId,
            columnId: openColumnId,
            prevState: visualizationState,
            frame: framePublicAPI,
          })
        );
      } else {
        if (forceRender) {
          updateDatasource(datasourceId, newState);
        } else {
          updateDatasourceAsync(datasourceId, newState);
        }
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [
      openDimension,
      openColumnGroup,
      openColumnId,
      activeVisualization,
      datasourceId,
      layerId,
      updateAll,
      updateDatasourceAsync,
      visualizationState,
      framePublicAPI,
    ]
  );

  const { dataViews } = props.framePublicAPI;
  const [datasource] = Object.values(framePublicAPI.datasourceLayers);
  const isTextBasedLanguage =
    datasource?.isTextBasedLanguage() ||
    isOfAggregateQueryType(editorProps.attributes?.state.query) ||
    false;

  const visualizationLayerSettings = useMemo(
    () =>
      activeVisualization.hasLayerSettings?.({
        layerId,
        state: visualizationState,
        frame: props.framePublicAPI,
      }) || { data: false, appearance: false },
    [activeVisualization, layerId, props.framePublicAPI, visualizationState]
  );

  const compatibleActions = useMemo<LayerAction[]>(
    () =>
      [
        ...(activeVisualization
          .getSupportedActionsForLayer?.(
            layerId,
            visualizationState,
            updateVisualization,
            props.registerLibraryAnnotationGroup,
            isSaveable
          )
          .map((action) => ({
            ...action,
            execute: () => {
              action.execute(layerActionsFlyoutRef.current);
            },
          })) || []),

        ...getSharedActions({
          layerId,
          activeVisualization,
          core,
          layerIndex,
          layerType: activeVisualization.getLayerType(layerId, visualizationState),
          isOnlyLayer,
          isTextBasedLanguage,
          hasLayerSettings: Boolean(
            (Object.values(visualizationLayerSettings).some(Boolean) &&
              activeVisualization.LayerSettingsComponent) ||
              layerDatasource?.LayerSettingsComponent
          ),
          openLayerSettings: () => setPanelSettingsOpen(true),
          onCloneLayer,
          onRemoveLayer: () => onRemoveLayer(layerId),
          customRemoveModalText: activeVisualization.getCustomRemoveLayerText?.(
            layerId,
            visualizationState
          ),
        }),
      ].filter((i) => i.isCompatible),
    [
      activeVisualization,
      layerId,
      visualizationState,
      updateVisualization,
      props.registerLibraryAnnotationGroup,
      isSaveable,
      core,
      layerIndex,
      isOnlyLayer,
      isTextBasedLanguage,
      visualizationLayerSettings,
      layerDatasource?.LayerSettingsComponent,
      onCloneLayer,
      onRemoveLayer,
    ]
  );
  const layerActionsFlyoutRef = useRef<HTMLDivElement | null>(null);

  return (
    <>
      <section
        tabIndex={-1}
        ref={registerLayerRef}
        css={css`
          margin-bottom: ${euiTheme.size.base};
          // disable focus ring for mouse clicks, leave it for keyboard users
          &:focus:not(:focus-visible) {
            animation: none !important; // sass-lint:disable-line no-important
          }
        `}
        data-test-subj={`lns-layerPanel-${layerIndex}`}
      >
        <EuiPanel paddingSize="none" hasShadow={false} hasBorder>
          <header
            className="lnsLayerPanel__layerHeader"
            css={css`
              padding: ${euiTheme.size.base};
              border-bottom: ${euiTheme.border.thin};
            `}
          >
            <EuiFlexGroup gutterSize="s" responsive={false} alignItems="center">
              <EuiFlexItem
                grow
                css={css`
                  min-width: 0; // fixes truncation for too long chart switcher labels
                `}
              >
                <LayerHeader
                  layerConfigProps={{
                    ...layerVisualizationConfigProps,
                    setState: props.updateVisualization,
                    onChangeIndexPattern: (indexPatternId) =>
                      onChangeIndexPattern({
                        indexPatternId,
                        layerId,
                        visualizationId: activeVisualization.id,
                      }),
                  }}
                  activeVisualizationId={activeVisualization.id}
                  visualizationMap={visualizationMap}
                  datasourceMap={datasourceMap}
                  onlyAllowSwitchToSubtypes={onlyAllowSwitchToSubtypes}
                />
              </EuiFlexItem>
              {props.displayLayerSettings && (
                <EuiFlexItem grow={false}>
                  <LayerActions
                    actions={compatibleActions}
                    layerIndex={layerIndex}
                    mountingPoint={layerActionsFlyoutRef.current}
                  />
                  <div ref={layerActionsFlyoutRef} />
                </EuiFlexItem>
              )}
            </EuiFlexGroup>
            {props.indexPatternService &&
              !isTextBasedLanguage &&
              (layerDatasource || activeVisualization.LayerPanelComponent) && (
                <EuiSpacer size="s" />
              )}
            {layerDatasource && props.indexPatternService && !isTextBasedLanguage && (
              <layerDatasource.LayerPanelComponent
                {...{
                  layerId,
                  state: layerDatasourceState,
                  activeData: props.framePublicAPI.activeData,
                  dataViews,
                  onChangeIndexPattern: (indexPatternId) =>
                    onChangeIndexPattern({ indexPatternId, layerId, datasourceId }),
                }}
              />
            )}
            <ESQLEditor
              isTextBasedLanguage={isTextBasedLanguage}
              framePublicAPI={framePublicAPI}
              datasourceMap={datasourceMap}
              layerId={layerId}
              visualizationMap={visualizationMap}
              {...editorProps}
            />
            {activeVisualization.LayerPanelComponent && (
              <activeVisualization.LayerPanelComponent
                {...{
                  layerId,
                  state: visualizationState,
                  frame: framePublicAPI,
                  setState: props.updateVisualization,
                  onChangeIndexPattern: (indexPatternId) =>
                    onChangeIndexPattern({
                      indexPatternId,
                      layerId,
                      visualizationId: activeVisualization.id,
                    }),
                }}
              />
            )}
          </header>

          {dimensionGroups
            .filter((group) => !group.isHidden)
            .map((group, groupIndex) => {
              let errorText: string = '';

              if (!isEmptyLayer || isInlineEditing) {
                if (
                  group.requiredMinDimensionCount &&
                  group.requiredMinDimensionCount > group.accessors.length
                ) {
                  if (group.requiredMinDimensionCount > 1) {
                    errorText = i18n.translate(
                      'xpack.lens.editorFrame.requiresTwoOrMoreFieldsWarningLabel',
                      {
                        defaultMessage: 'Requires {requiredMinDimensionCount} fields',
                        values: {
                          requiredMinDimensionCount: group.requiredMinDimensionCount,
                        },
                      }
                    );
                  } else {
                    errorText = i18n.translate('xpack.lens.editorFrame.requiresFieldWarningLabel', {
                      defaultMessage: 'Requires field',
                    });
                  }
                } else if (group.dimensionsTooMany && group.dimensionsTooMany > 0) {
                  errorText = i18n.translate(
                    'xpack.lens.editorFrame.tooManyDimensionsSingularWarningLabel',
                    {
                      defaultMessage:
                        'Please remove {dimensionsTooMany, plural, one {a dimension} other {{dimensionsTooMany} dimensions}}',
                      values: {
                        dimensionsTooMany: group.dimensionsTooMany,
                      },
                    }
                  );
                }
              }
              const isOptional = !group.requiredMinDimensionCount && !group.suggestedValue;
              return (
                <EuiFormRow
                  css={css`
                    padding: ${euiTheme.size.base};
                    &:last-child {
                      border-radius: 0 0 ${euiTheme.border.radius.medium}
                        ${euiTheme.border.radius.medium};
                    }

                    // Add border to the top of the next same panel
                    & + & {
                      border-top: ${euiTheme.border.thin};
                      margin-top: 0;
                    }

                    & > * {
                      margin-bottom: 0;
                    }

                    // Targeting EUI class as we are unable to apply a class to this element in component
                    &,
                    .euiFormRow__fieldWrapper {
                      & > * + * {
                        margin-top: ${euiTheme.size.s};
                      }
                    }
                  `}
                  className="lnsLayerPanel__row"
                  fullWidth
                  label={
                    <>
                      {group.groupLabel}
                      {group.groupTooltip && (
                        <>
                          <EuiIconTip
                            color="subdued"
                            content={group.groupTooltip}
                            iconProps={{
                              className: 'eui-alignTop',
                            }}
                            position="top"
                            size="s"
                            type="questionInCircle"
                          />
                        </>
                      )}
                    </>
                  }
                  labelAppend={
                    isOptional ? (
                      <EuiText color="subdued" size="xs" data-test-subj="lnsGroup_optional">
                        {i18n.translate('xpack.lens.editorFrame.optionalDimensionLabel', {
                          defaultMessage: 'Optional',
                        })}
                      </EuiText>
                    ) : null
                  }
                  labelType="legend"
                  key={group.groupId}
                  isInvalid={Boolean(errorText)}
                  error={errorText}
                >
                  <>
                    {group.accessors.length ? (
                      <ReorderProvider
                        dataTestSubj="lnsDragDrop"
                        css={css`
                          margin: -${euiTheme.size.xs} -${euiTheme.size.base};
                          padding: ${euiTheme.size.xs} ${euiTheme.size.base};
                        `}
                      >
                        {group.accessors.map((accessorConfig, accessorIndex) => {
                          const { columnId } = accessorConfig;

                          const messages =
                            props?.getUserMessages?.('dimensionButton', {
                              dimensionId: columnId,
                            }) ?? [];
                          const firstMessage = messages.at(0);

                          return (
                            <DraggableDimensionButton
                              activeVisualization={activeVisualization}
                              registerNewButtonRef={registerNewButtonRef}
                              order={[2, layerIndex, groupIndex, accessorIndex]}
                              target={{
                                id: columnId,
                                layerId,
                                columnId,
                                groupId: group.groupId,
                                filterOperations: group.filterOperations,
                                prioritizedOperation: group.prioritizedOperation,
                                isMetricDimension: group?.isMetricDimension,
                                indexPatternId: layerDatasource
                                  ? layerDatasource.getUsedDataView(layerDatasourceState, layerId)
                                  : activeVisualization.getUsedDataView?.(
                                      visualizationState,
                                      layerId
                                    ),
                                humanData: {
                                  label: columnLabelMap?.[columnId] ?? '',
                                  groupLabel: group.groupLabel,
                                  position: accessorIndex + 1,
                                  layerNumber: layerIndex + 1,
                                },
                              }}
                              group={group}
                              key={columnId}
                              state={layerDatasourceState}
                              layerDatasource={layerDatasource}
                              datasourceLayers={framePublicAPI.datasourceLayers}
                              onDrop={onDrop}
                              indexPatterns={dataViews.indexPatterns}
                            >
                              <DimensionButton
                                accessorConfig={accessorConfig}
                                label={columnLabelMap?.[accessorConfig.columnId] ?? ''}
                                groupLabel={group.groupLabel}
                                onClick={(id: string) => {
                                  setOpenDimension({
                                    openColumnGroup: group,
                                    openColumnId: id,
                                  });
                                }}
                                onRemoveClick={(id: string) => {
                                  props.onRemoveDimension({ columnId: id, layerId });
                                  removeButtonRef(id);
                                }}
                                message={
                                  firstMessage
                                    ? {
                                        severity: firstMessage.severity,
                                        content:
                                          firstMessage.shortMessage || getLongMessage(firstMessage),
                                      }
                                    : undefined
                                }
                              >
                                {layerDatasource ? (
                                  <>
                                    {layerDatasource.DimensionTriggerComponent({
                                      ...layerDatasourceConfigProps,
                                      columnId: accessorConfig.columnId,
                                      groupId: group.groupId,
                                      filterOperations: group.filterOperations,
                                      indexPatterns: dataViews.indexPatterns,
                                    })}
                                  </>
                                ) : (
                                  <>
                                    {activeVisualization?.DimensionTriggerComponent?.({
                                      columnId,
                                      label: columnLabelMap?.[columnId] ?? '',
                                    })}
                                  </>
                                )}
                              </DimensionButton>
                            </DraggableDimensionButton>
                          );
                        })}
                      </ReorderProvider>
                    ) : null}

                    {group.fakeFinalAccessor && (
                      <FakeDimensionButton label={group.fakeFinalAccessor.label} />
                    )}

                    {group.supportsMoreColumns ? (
                      <EmptyDimensionButton
                        activeVisualization={activeVisualization}
                        order={[2, layerIndex, groupIndex, group.accessors.length]}
                        group={group}
                        target={{
                          layerId,
                          groupId: group.groupId,
                          filterOperations: group.filterOperations,
                          prioritizedOperation: group.prioritizedOperation,
                          isNewColumn: true,
                          isMetricDimension: group?.isMetricDimension,
                          indexPatternId: layerDatasource
                            ? layerDatasource.getUsedDataView(layerDatasourceState, layerId)
                            : activeVisualization.getUsedDataView?.(visualizationState, layerId),
                          humanData: {
                            groupLabel: group.groupLabel,
                            layerNumber: layerIndex + 1,
                            position: group.accessors.length + 1,
                            label: i18n.translate('xpack.lens.indexPattern.emptyDimensionButton', {
                              defaultMessage: 'Empty dimension',
                            }),
                          },
                        }}
                        layerDatasource={layerDatasource}
                        state={layerDatasourceState}
                        datasourceLayers={framePublicAPI.datasourceLayers}
                        onClick={(id) => {
                          props.onEmptyDimensionAdd(id, group);
                          setOpenDimension({
                            openColumnGroup: group,
                            openColumnId: id,
                          });
                        }}
                        onDrop={onDrop}
                        indexPatterns={dataViews.indexPatterns}
                        isInlineEditing={isInlineEditing}
                      />
                    ) : null}
                  </>
                </EuiFormRow>
              );
            })}
        </EuiPanel>
      </section>
      {(layerDatasource?.LayerSettingsComponent || activeVisualization?.LayerSettingsComponent) && (
        <FlyoutContainer
          panelRef={(el) => (settingsPanelRef.current = el)}
          isFullscreen={false}
          label={i18n.translate('xpack.lens.editorFrame.layerSettingsTitle', {
            defaultMessage: 'Layer settings',
          })}
          isOpen={isPanelSettingsOpen}
          handleClose={() => {
            setPanelSettingsOpen(false);
          }}
          isInlineEditing={isInlineEditing}
        >
          <div id={layerId}>
            <div className="lnsIndexPatternDimensionEditor--padded">
              {layerDatasource?.LayerSettingsComponent || visualizationLayerSettings.data ? (
                <EuiText
                  size="s"
                  css={css`
                    margin-bottom: ${euiThemeVars.euiSize};
                  `}
                >
                  <h4>
                    {i18n.translate('xpack.lens.editorFrame.layerSettings.headingData', {
                      defaultMessage: 'Data',
                    })}
                  </h4>
                </EuiText>
              ) : null}
              {layerDatasource?.LayerSettingsComponent && (
                <layerDatasource.LayerSettingsComponent {...layerDatasourceConfigProps} />
              )}
              {activeVisualization?.LayerSettingsComponent && visualizationLayerSettings.data ? (
                <activeVisualization.LayerSettingsComponent
                  {...{
                    ...layerVisualizationConfigProps,
                    setState: props.updateVisualization,
                    panelRef: settingsPanelRef,
                    section: 'data',
                  }}
                />
              ) : null}
              {visualizationLayerSettings.appearance ? (
                <EuiText
                  size="s"
                  css={css`
                    margin-bottom: ${euiThemeVars.euiSize};
                  `}
                >
                  <h4>
                    {i18n.translate('xpack.lens.editorFrame.layerSettings.headingAppearance', {
                      defaultMessage: 'Appearance',
                    })}
                  </h4>
                </EuiText>
              ) : null}
              {activeVisualization?.LayerSettingsComponent && (
                <activeVisualization.LayerSettingsComponent
                  {...{
                    ...layerVisualizationConfigProps,
                    setState: props.updateVisualization,
                    panelRef: settingsPanelRef,
                    section: 'appearance',
                  }}
                />
              )}
            </div>
          </div>
        </FlyoutContainer>
      )}
      <DimensionContainer
        panelRef={(el) => (panelRef.current = el)}
        isOpen={isDimensionPanelOpen}
        isFullscreen={isFullscreen}
        label={openColumnGroup?.dimensionEditorGroupLabel ?? (openColumnGroup?.groupLabel || '')}
        isInlineEditing={isInlineEditing}
        handleClose={closeDimensionEditor}
        panel={
          <div>
            {openColumnGroup &&
              openColumnId &&
              layerDatasource &&
              layerDatasource.DimensionEditorComponent({
                ...layerDatasourceConfigProps,
                core: props.core,
                columnId: openColumnId,
                groupId: openColumnGroup.groupId,
                hideGrouping: openColumnGroup.hideGrouping,
                filterOperations: openColumnGroup.filterOperations,
                isMetricDimension: openColumnGroup?.isMetricDimension,
                dimensionGroups,
                toggleFullscreen,
                isFullscreen,
                setState: updateDataLayerState,
                supportStaticValue: Boolean(openColumnGroup.supportStaticValue),
                paramEditorCustomProps: openColumnGroup.paramEditorCustomProps,
                enableFormatSelector: openColumnGroup.enableFormatSelector !== false,
                layerType: activeVisualization.getLayerType(layerId, visualizationState),
                indexPatterns: dataViews.indexPatterns,
                activeData: layerVisualizationConfigProps.activeData,
                dataSectionExtra: !isFullscreen &&
                  openDimension.isComplete &&
                  activeVisualization.DimensionEditorDataExtraComponent && (
                    <activeVisualization.DimensionEditorDataExtraComponent
                      {...{
                        ...layerVisualizationConfigProps,
                        groupId: openColumnGroup.groupId,
                        accessor: openColumnId,
                        datasource,
                        setState: props.updateVisualization,
                        addLayer: props.addLayer,
                        removeLayer: props.onRemoveLayer,
                        panelRef,
                      }}
                    />
                  ),
              })}
            {openColumnGroup &&
              openColumnId &&
              !isFullscreen &&
              openDimension.isComplete &&
              activeVisualization.DimensionEditorComponent &&
              openColumnGroup?.enableDimensionEditor && (
                <>
                  <div
                    css={css`
                      padding: ${euiTheme.size.base};
                    `}
                  >
                    <activeVisualization.DimensionEditorComponent
                      {...{
                        ...layerVisualizationConfigProps,
                        groupId: openColumnGroup.groupId,
                        accessor: openColumnId,
                        datasource,
                        setState: props.updateVisualization,
                        addLayer: props.addLayer,
                        removeLayer: props.onRemoveLayer,
                        panelRef,
                        isInlineEditing,
                      }}
                    />
                  </div>
                  {activeVisualization.DimensionEditorAdditionalSectionComponent && (
                    <activeVisualization.DimensionEditorAdditionalSectionComponent
                      {...{
                        ...layerVisualizationConfigProps,
                        groupId: openColumnGroup.groupId,
                        accessor: openColumnId,
                        datasource,
                        setState: props.updateVisualization,
                        addLayer: props.addLayer,
                        removeLayer: props.onRemoveLayer,
                        panelRef,
                      }}
                    />
                  )}
                </>
              )}
          </div>
        }
      />
    </>
  );
}