[control group] do not render control group when there are no controls (#190521)

PR updates ControlGroup to not render any components when there are no
controls. PR also removes loading state from ControlGroup, as suggested
by @ThomThomson

#### Before
<img width="600" alt="Screenshot 2024-08-14 at 9 18 57 AM"
src="https://github.com/user-attachments/assets/e52aabf5-7322-4d8e-838c-d56524ece55e">


### Test instructions
1. start kibana with `yarn start --run-examples`
2. Open controls example at http://localhost:5601/app/controlsExamples
3. Remove all controls. Notice how the ControlGroup no longer takes up
any empty vertical spacing
<img width="600" alt="Screenshot 2024-08-14 at 9 15 53 AM"
src="https://github.com/user-attachments/assets/374ddec4-30c5-46fb-8ed9-c8c41a35fc1e">
This commit is contained in:
Nathan Reese 2024-08-14 12:15:59 -06:00 committed by GitHub
parent fc12e58c2f
commit 19e9bfb26e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 31 additions and 12 deletions

View file

@ -219,6 +219,19 @@ export const ReactControlExample = ({
};
}, [controlGroupApi, timeslice$]);
const [hasControls, setHasControls] = useState(false);
useEffect(() => {
if (!controlGroupApi) {
return;
}
const subscription = controlGroupApi.children$.subscribe((children) => {
setHasControls(Object.keys(children).length > 0);
});
return () => {
subscription.unsubscribe();
};
}, [controlGroupApi]);
useEffect(() => {
const subscription = combineLatest([controlGroupFilters$, unifiedSearchFilters$]).subscribe(
([controlGroupFilters, unifiedSearchFilters]) => {
@ -389,7 +402,7 @@ export const ReactControlExample = ({
reload$.next();
}}
/>
<EuiSpacer size="m" />
{hasControls && <EuiSpacer size="m" />}
<ReactEmbeddableRenderer
onApiAvailable={(api) => {
dashboardApi?.setChild(api);
@ -402,6 +415,7 @@ export const ReactControlExample = ({
getSerializedStateForChild: getControlGroupSerializedState,
getRuntimeStateForChild: getControlGroupRuntimeState,
})}
panelProps={{ hideLoader: true }}
key={`control_group`}
/>
<EuiSpacer size="l" />

View file

@ -7,6 +7,7 @@
*/
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { css } from '@emotion/react';
import { BehaviorSubject } from 'rxjs';
import {
DndContext,
@ -24,14 +25,7 @@ import {
SortableContext,
sortableKeyboardCoordinates,
} from '@dnd-kit/sortable';
import {
EuiButtonIcon,
EuiFlexGroup,
EuiFlexItem,
EuiLoadingChart,
EuiPanel,
EuiToolTip,
} from '@elastic/eui';
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiToolTip } from '@elastic/eui';
import { useBatchedPublishingSubjects } from '@kbn/presentation-publishing';
import { ControlStyle } from '../../..';
import { ControlsInOrder } from '../init_controls_manager';
@ -114,8 +108,15 @@ export function ControlGroup({
);
}, [hasUnappliedSelections, applySelections]);
if (controlsInOrder.length === 0) {
return null;
}
return (
<EuiPanel
css={css`
display: ${isInitialized ? 'none' : 'default'};
`}
borderRadius="m"
paddingSize="none"
color={draggingId ? 'success' : 'transparent'}
@ -127,7 +128,6 @@ export function ControlGroup({
responsive={false}
data-test-subj="controls-group"
>
{!isInitialized && <EuiLoadingChart />}
<EuiFlexItem>
<DndContext
onDragStart={({ active }) => setDraggingId(`${active.id}`)}
@ -167,7 +167,7 @@ export function ControlGroup({
</DragOverlay>
</DndContext>
</EuiFlexItem>
{isInitialized && !autoApplySelections && (
{!autoApplySelections && (
<EuiFlexItem grow={false} className="controlGroup--endButtonGroup">
{hasUnappliedSelections ? (
ApplyButtonComponent

View file

@ -65,6 +65,7 @@ export const ReactEmbeddableRenderer = <
| 'showBorder'
| 'showBadges'
| 'showNotifications'
| 'hideLoader'
| 'hideHeader'
| 'hideInspector'
>;

View file

@ -50,7 +50,7 @@ export const PresentationPanel = <
}, []);
if (loading)
return (
return props.hideLoader ? null : (
<PanelLoader
showShadow={props.showShadow}
showBorder={props.showBorder}

View file

@ -40,6 +40,10 @@ export interface PresentationPanelInternalProps<
showBadges?: boolean;
showNotifications?: boolean;
/**
* Set to true to not show PanelLoader component while Panel is loading
*/
hideLoader?: boolean;
hideHeader?: boolean;
hideInspector?: boolean;