mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Controls] Close controls flyouts on unmount, save, and view mode change (#128198)
* Manage flyout via global ref in control group container * Add functional tests for settings flyout
This commit is contained in:
parent
75c5cf2093
commit
dd9aa84724
6 changed files with 66 additions and 11 deletions
|
@ -16,6 +16,7 @@ import { ControlGroupStrings } from '../control_group_strings';
|
|||
import { ControlWidth, ControlInput, IEditableControlFactory } from '../../types';
|
||||
import { toMountPoint } from '../../../../kibana_react/public';
|
||||
import { DEFAULT_CONTROL_WIDTH } from '../../../common/control_group/control_group_constants';
|
||||
import { setFlyoutRef } from '../embeddable/control_group_container';
|
||||
|
||||
export type CreateControlButtonTypes = 'toolbar' | 'callout';
|
||||
export interface CreateControlButtonProps {
|
||||
|
@ -99,9 +100,13 @@ export const CreateControlButton = ({
|
|||
),
|
||||
{
|
||||
outsideClickCloses: false,
|
||||
onClose: (flyout) => onCancel(flyout),
|
||||
onClose: (flyout) => {
|
||||
onCancel(flyout);
|
||||
setFlyoutRef(undefined);
|
||||
},
|
||||
}
|
||||
);
|
||||
setFlyoutRef(flyoutInstance);
|
||||
});
|
||||
|
||||
initialInputPromise.then(
|
||||
|
|
|
@ -20,7 +20,7 @@ import { IEditableControlFactory, ControlInput } from '../../types';
|
|||
import { controlGroupReducers } from '../state/control_group_reducers';
|
||||
import { EmbeddableFactoryNotFoundError } from '../../../../embeddable/public';
|
||||
import { useReduxContainerContext } from '../../../../presentation_util/public';
|
||||
import { ControlGroupContainer } from '../embeddable/control_group_container';
|
||||
import { ControlGroupContainer, setFlyoutRef } from '../embeddable/control_group_container';
|
||||
|
||||
export const EditControlButton = ({ embeddableId }: { embeddableId: string }) => {
|
||||
// Controls Services Context
|
||||
|
@ -127,9 +127,13 @@ export const EditControlButton = ({ embeddableId }: { embeddableId: string }) =>
|
|||
),
|
||||
{
|
||||
outsideClickCloses: false,
|
||||
onClose: (flyout) => onCancel(flyout),
|
||||
onClose: (flyout) => {
|
||||
setFlyoutRef(undefined);
|
||||
onCancel(flyout);
|
||||
},
|
||||
}
|
||||
);
|
||||
setFlyoutRef(flyoutInstance);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -15,6 +15,7 @@ import { ControlGroupEditor } from './control_group_editor';
|
|||
import { OverlayRef } from '../../../../../core/public';
|
||||
import { pluginServices } from '../../services';
|
||||
import { ControlGroupContainer } from '..';
|
||||
import { setFlyoutRef } from '../embeddable/control_group_container';
|
||||
|
||||
export interface EditControlGroupButtonProps {
|
||||
controlGroupContainer: ControlGroupContainer;
|
||||
|
@ -60,9 +61,13 @@ export const EditControlGroup = ({
|
|||
),
|
||||
{
|
||||
outsideClickCloses: false,
|
||||
onClose: () => flyoutInstance.close(),
|
||||
onClose: () => {
|
||||
flyoutInstance.close();
|
||||
setFlyoutRef(undefined);
|
||||
},
|
||||
}
|
||||
);
|
||||
setFlyoutRef(flyoutInstance);
|
||||
};
|
||||
|
||||
const commonButtonProps = {
|
||||
|
|
|
@ -46,11 +46,17 @@ import { Container, EmbeddableFactory } from '../../../../embeddable/public';
|
|||
import { ControlEmbeddable, ControlInput, ControlOutput } from '../../types';
|
||||
import { ControlGroupChainingSystems } from './control_group_chaining_system';
|
||||
import { CreateControlButton, CreateControlButtonTypes } from '../editor/create_control';
|
||||
import { OverlayRef } from '../../../../../core/public';
|
||||
|
||||
const ControlGroupReduxWrapper = withSuspense<
|
||||
ReduxEmbeddableWrapperPropsWithChildren<ControlGroupInput>
|
||||
>(LazyReduxEmbeddableWrapper);
|
||||
|
||||
let flyoutRef: OverlayRef | undefined;
|
||||
export const setFlyoutRef = (newRef: OverlayRef | undefined) => {
|
||||
flyoutRef = newRef;
|
||||
};
|
||||
|
||||
export interface ChildEmbeddableOrderCache {
|
||||
IdsToOrder: { [key: string]: number };
|
||||
idsInOrder: string[];
|
||||
|
@ -96,6 +102,11 @@ export class ControlGroupContainer extends Container<
|
|||
return this.lastUsedDataViewId ?? this.relevantDataViewId;
|
||||
};
|
||||
|
||||
public closeAllFlyouts() {
|
||||
flyoutRef?.close();
|
||||
flyoutRef = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a button that allows controls to be created externally using the embeddable
|
||||
* @param buttonType Controls the button styling
|
||||
|
@ -367,6 +378,7 @@ export class ControlGroupContainer extends Container<
|
|||
|
||||
public destroy() {
|
||||
super.destroy();
|
||||
this.closeAllFlyouts();
|
||||
this.subscriptions.unsubscribe();
|
||||
if (this.domNode) ReactDOM.unmountComponentAtNode(this.domNode);
|
||||
}
|
||||
|
|
|
@ -210,16 +210,17 @@ export function DashboardTopNav({
|
|||
[stateTransferService, data.search.session, trackUiMetric]
|
||||
);
|
||||
|
||||
const clearAddPanel = useCallback(() => {
|
||||
const closeAllFlyouts = useCallback(() => {
|
||||
dashboardAppState.dashboardContainer.controlGroup?.closeAllFlyouts();
|
||||
if (state.addPanelOverlay) {
|
||||
state.addPanelOverlay.close();
|
||||
setState((s) => ({ ...s, addPanelOverlay: undefined }));
|
||||
}
|
||||
}, [state.addPanelOverlay]);
|
||||
}, [state.addPanelOverlay, dashboardAppState.dashboardContainer.controlGroup]);
|
||||
|
||||
const onChangeViewMode = useCallback(
|
||||
(newMode: ViewMode) => {
|
||||
clearAddPanel();
|
||||
closeAllFlyouts();
|
||||
const willLoseChanges = newMode === ViewMode.VIEW && dashboardAppState.hasUnsavedChanges;
|
||||
|
||||
if (!willLoseChanges) {
|
||||
|
@ -231,7 +232,7 @@ export function DashboardTopNav({
|
|||
dashboardAppState.resetToLastSavedState?.()
|
||||
);
|
||||
},
|
||||
[clearAddPanel, core.overlays, dashboardAppState, dispatchDashboardStateChange]
|
||||
[closeAllFlyouts, core.overlays, dashboardAppState, dispatchDashboardStateChange]
|
||||
);
|
||||
|
||||
const runSaveAs = useCallback(async () => {
|
||||
|
@ -296,7 +297,7 @@ export function DashboardTopNav({
|
|||
showCopyOnSave={lastDashboardId ? true : false}
|
||||
/>
|
||||
);
|
||||
clearAddPanel();
|
||||
closeAllFlyouts();
|
||||
showSaveModal(dashboardSaveModal, core.i18n.Context);
|
||||
}, [
|
||||
dispatchDashboardStateChange,
|
||||
|
@ -305,7 +306,7 @@ export function DashboardTopNav({
|
|||
dashboardAppState,
|
||||
core.i18n.Context,
|
||||
chrome.docTitle,
|
||||
clearAddPanel,
|
||||
closeAllFlyouts,
|
||||
kibanaVersion,
|
||||
timefilter,
|
||||
redirectTo,
|
||||
|
@ -468,7 +469,7 @@ export function DashboardTopNav({
|
|||
]);
|
||||
|
||||
UseUnmount(() => {
|
||||
clearAddPanel();
|
||||
closeAllFlyouts();
|
||||
setMounted(false);
|
||||
});
|
||||
|
||||
|
|
|
@ -99,5 +99,33 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await dashboardControls.deleteAllControls();
|
||||
});
|
||||
});
|
||||
|
||||
describe('control group settings flyout closes', async () => {
|
||||
it('on save', async () => {
|
||||
await dashboardControls.openControlGroupSettingsFlyout();
|
||||
await dashboard.saveDashboard('Test Control Group Settings', {
|
||||
saveAsNew: false,
|
||||
exitFromEditMode: false,
|
||||
});
|
||||
await testSubjects.missingOrFail('control-group-settings-flyout');
|
||||
});
|
||||
|
||||
it('on view mode change', async () => {
|
||||
await dashboardControls.openControlGroupSettingsFlyout();
|
||||
await dashboard.clickCancelOutOfEditMode();
|
||||
await testSubjects.missingOrFail('control-group-settings-flyout');
|
||||
});
|
||||
|
||||
it('when navigating away from dashboard', async () => {
|
||||
await dashboard.switchToEditMode();
|
||||
await dashboardControls.openControlGroupSettingsFlyout();
|
||||
await dashboard.gotoDashboardLandingPage();
|
||||
await testSubjects.missingOrFail('control-group-settings-flyout');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await dashboard.loadSavedDashboard('Test Control Group Settings');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue