[maps] implement save and return from dashboard (#74303)
* pass originatingApp into App * save and return top nav option * clean up * navigate to originating app * functional test * tslint * cutOriginatingAppConnection * add functional test for cutting originating app flow * one more fix for cutting originator app and another functional test to verify * typo * review feedback Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
178afd71fc
commit
ed69f9b85a
|
@ -70,6 +70,17 @@ export function DashboardPanelActionsProvider({ getService, getPageObjects }: Ft
|
|||
await PageObjects.common.waitForTopNavToBeVisible();
|
||||
}
|
||||
|
||||
async editPanelByTitle(title?: string) {
|
||||
log.debug(`editPanelByTitle(${title})`);
|
||||
if (title) {
|
||||
const panelOptions = await this.getPanelHeading(title);
|
||||
await this.openContextMenu(panelOptions);
|
||||
} else {
|
||||
await this.openContextMenu();
|
||||
}
|
||||
await testSubjects.clickWhenNotDisabled(EDIT_PANEL_DATA_TEST_SUBJ);
|
||||
}
|
||||
|
||||
async clickExpandPanelToggle() {
|
||||
await testSubjects.click(TOGGLE_EXPAND_PANEL_DATA_TEST_SUBJ);
|
||||
}
|
||||
|
|
11
x-pack/plugins/maps/public/kibana_services.d.ts
vendored
11
x-pack/plugins/maps/public/kibana_services.d.ts
vendored
|
@ -6,8 +6,10 @@
|
|||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { IndexPatternsService } from 'src/plugins/data/public/index_patterns';
|
||||
import { NavigateToAppOptions } from 'kibana/public';
|
||||
import { MapsConfigType } from '../config';
|
||||
import { MapsLegacyConfigType } from '../../../../src/plugins/maps_legacy/public';
|
||||
import { EmbeddableStart } from '../../../../src/plugins/embeddable/public';
|
||||
|
||||
export function getLicenseId(): any;
|
||||
export function getInspector(): any;
|
||||
|
@ -77,3 +79,12 @@ export function setKibanaCommonConfig(config: MapsLegacyConfigType): void;
|
|||
export function setMapAppConfig(config: MapsConfigType): void;
|
||||
export function setKibanaVersion(version: string): void;
|
||||
export function setIsGoldPlus(isGoldPlus: boolean): void;
|
||||
export function setEmbeddableService(embeddableService: EmbeddableStart): void;
|
||||
export function getEmbeddableService(): EmbeddableStart;
|
||||
export function setNavigateToApp(
|
||||
navigateToApp: (appId: string, options?: NavigateToAppOptions | undefined) => Promise<void>
|
||||
): void;
|
||||
export const navigateToApp: (
|
||||
appId: string,
|
||||
options?: NavigateToAppOptions | undefined
|
||||
) => Promise<void>;
|
||||
|
|
|
@ -177,3 +177,16 @@ export const setIsGoldPlus = (igp) => {
|
|||
export const getIsGoldPlus = () => {
|
||||
return isGoldPlus;
|
||||
};
|
||||
|
||||
let embeddableService;
|
||||
export const setEmbeddableService = (_embeddableService) => {
|
||||
embeddableService = _embeddableService;
|
||||
};
|
||||
export const getEmbeddableService = () => {
|
||||
return embeddableService;
|
||||
};
|
||||
|
||||
export let navigateToApp;
|
||||
export function setNavigateToApp(_navigateToApp) {
|
||||
navigateToApp = _navigateToApp;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ import {
|
|||
setUiActions,
|
||||
setUiSettings,
|
||||
setVisualizations,
|
||||
setEmbeddableService,
|
||||
setNavigateToApp,
|
||||
} from './kibana_services';
|
||||
import { featureCatalogueEntry } from './feature_catalogue_entry';
|
||||
// @ts-ignore
|
||||
|
@ -113,6 +115,8 @@ export const bindStartCoreAndPlugins = (core: CoreStart, plugins: any) => {
|
|||
setUiActions(plugins.uiActions);
|
||||
setNavigation(plugins.navigation);
|
||||
setCoreI18n(core.i18n);
|
||||
setEmbeddableService(plugins.embeddable);
|
||||
setNavigateToApp(core.application.navigateToApp);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,7 @@ export interface ISavedGisMap extends SavedObject {
|
|||
layerListJSON?: string;
|
||||
mapStateJSON?: string;
|
||||
uiStateJSON?: string;
|
||||
description?: string;
|
||||
getLayerList(): LayerDescriptor[];
|
||||
syncWithStore(): void;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { Router, Switch, Route, Redirect } from 'react-router-dom';
|
||||
import { getCoreI18n, getToasts } from '../kibana_services';
|
||||
import { getCoreI18n, getToasts, getEmbeddableService } from '../kibana_services';
|
||||
import {
|
||||
createKbnUrlStateStorage,
|
||||
withNotifyOnErrors,
|
||||
|
@ -39,6 +39,11 @@ const App = ({ history, appBasePath, onAppLeave }) => {
|
|||
const store = getStore();
|
||||
const I18nContext = getCoreI18n().Context;
|
||||
|
||||
const stateTransfer = getEmbeddableService()?.getStateTransfer(history);
|
||||
|
||||
const { originatingApp } =
|
||||
stateTransfer?.getIncomingEditorState({ keysToRemoveAfterFetch: ['originatingApp'] }) || {};
|
||||
|
||||
return (
|
||||
<I18nContext>
|
||||
<Provider store={store}>
|
||||
|
@ -50,13 +55,21 @@ const App = ({ history, appBasePath, onAppLeave }) => {
|
|||
<LoadMapAndRender
|
||||
savedMapId={props.match.params.savedMapId}
|
||||
onAppLeave={onAppLeave}
|
||||
stateTransfer={stateTransfer}
|
||||
originatingApp={originatingApp}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={`/map`}
|
||||
render={() => <LoadMapAndRender onAppLeave={onAppLeave} />}
|
||||
render={() => (
|
||||
<LoadMapAndRender
|
||||
onAppLeave={onAppLeave}
|
||||
stateTransfer={stateTransfer}
|
||||
originatingApp={originatingApp}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
// Redirect other routes to list, or if hash-containing, their non-hash equivalents
|
||||
<Route
|
||||
|
|
|
@ -29,7 +29,6 @@ import {
|
|||
updateFlyout,
|
||||
enableFullScreen,
|
||||
openMapSettings,
|
||||
removePreviewLayers,
|
||||
} from '../../../actions';
|
||||
import { FLYOUT_STATE } from '../../../reducers/ui';
|
||||
import { getMapsCapabilities } from '../../../kibana_services';
|
||||
|
@ -74,11 +73,6 @@ function mapDispatchToProps(dispatch) {
|
|||
dispatch(updateFlyout(FLYOUT_STATE.NONE));
|
||||
dispatch(setReadOnly(!getMapsCapabilities().save));
|
||||
},
|
||||
closeFlyout: () => {
|
||||
dispatch(setSelectedLayer(null));
|
||||
dispatch(updateFlyout(FLYOUT_STATE.NONE));
|
||||
dispatch(removePreviewLayers());
|
||||
},
|
||||
enableFullScreen: () => dispatch(enableFullScreen()),
|
||||
openMapSettings: () => dispatch(openMapSettings()),
|
||||
};
|
||||
|
|
|
@ -56,6 +56,13 @@ export const LoadMapAndRender = class extends React.Component {
|
|||
return <Redirect to="/" />;
|
||||
}
|
||||
|
||||
return savedMap ? <MapsAppView savedMap={savedMap} onAppLeave={this.props.onAppLeave} /> : null;
|
||||
return savedMap ? (
|
||||
<MapsAppView
|
||||
savedMap={savedMap}
|
||||
onAppLeave={this.props.onAppLeave}
|
||||
stateTransfer={this.props.stateTransfer}
|
||||
originatingApp={this.props.originatingApp}
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -51,6 +51,8 @@ export class MapsAppView extends React.Component {
|
|||
initialized: false,
|
||||
savedQuery: '',
|
||||
initialLayerListConfig: null,
|
||||
// tracking originatingApp in state so the connection can be broken by users
|
||||
originatingApp: props.originatingApp,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -311,11 +313,15 @@ export class MapsAppView extends React.Component {
|
|||
savedMap: this.props.savedMap,
|
||||
isOpenSettingsDisabled: this.props.isOpenSettingsDisabled,
|
||||
isSaveDisabled: this.props.isSaveDisabled,
|
||||
closeFlyout: this.props.closeFlyout,
|
||||
enableFullScreen: this.props.enableFullScreen,
|
||||
openMapSettings: this.props.openMapSettings,
|
||||
inspectorAdapters: this.props.inspectorAdapters,
|
||||
setBreadcrumbs: this._setBreadcrumbs,
|
||||
stateTransfer: this.props.stateTransfer,
|
||||
originatingApp: this.state.originatingApp,
|
||||
cutOriginatingAppConnection: () => {
|
||||
this.setState({ originatingApp: undefined });
|
||||
},
|
||||
});
|
||||
|
||||
const { TopNavMenu } = getNavigation().ui;
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Adapters } from 'src/plugins/inspector/public';
|
||||
import { SavedObjectSaveOpts } from 'src/plugins/saved_objects/public';
|
||||
import {
|
||||
getCoreChrome,
|
||||
getMapsCapabilities,
|
||||
getInspector,
|
||||
getToasts,
|
||||
getCoreI18n,
|
||||
navigateToApp,
|
||||
} from '../../../kibana_services';
|
||||
import {
|
||||
SavedObjectSaveModal,
|
||||
SavedObjectSaveModalOrigin,
|
||||
OnSaveProps,
|
||||
showSaveModal,
|
||||
} from '../../../../../../../src/plugins/saved_objects/public';
|
||||
|
@ -24,60 +24,181 @@ import { MAP_SAVED_OBJECT_TYPE } from '../../../../common/constants';
|
|||
// @ts-expect-error
|
||||
import { goToSpecifiedPath } from '../../maps_router';
|
||||
import { ISavedGisMap } from '../../bootstrap/services/saved_gis_map';
|
||||
import { EmbeddableStateTransfer } from '../../../../../../../src/plugins/embeddable/public';
|
||||
|
||||
export function getTopNavConfig({
|
||||
savedMap,
|
||||
isOpenSettingsDisabled,
|
||||
isSaveDisabled,
|
||||
closeFlyout,
|
||||
enableFullScreen,
|
||||
openMapSettings,
|
||||
inspectorAdapters,
|
||||
setBreadcrumbs,
|
||||
stateTransfer,
|
||||
originatingApp,
|
||||
cutOriginatingAppConnection,
|
||||
}: {
|
||||
savedMap: ISavedGisMap;
|
||||
isOpenSettingsDisabled: boolean;
|
||||
isSaveDisabled: boolean;
|
||||
closeFlyout: () => void;
|
||||
enableFullScreen: () => void;
|
||||
openMapSettings: () => void;
|
||||
inspectorAdapters: Adapters;
|
||||
setBreadcrumbs: () => void;
|
||||
stateTransfer?: EmbeddableStateTransfer;
|
||||
originatingApp?: string;
|
||||
cutOriginatingAppConnection: () => void;
|
||||
}) {
|
||||
return [
|
||||
{
|
||||
id: 'full-screen',
|
||||
label: i18n.translate('xpack.maps.mapController.fullScreenButtonLabel', {
|
||||
defaultMessage: `full screen`,
|
||||
const topNavConfigs = [];
|
||||
const isNewMap = !savedMap.id;
|
||||
const hasWritePermissions = getMapsCapabilities().save;
|
||||
const hasSaveAndReturnConfig = hasWritePermissions && !isNewMap && originatingApp;
|
||||
|
||||
async function onSave({
|
||||
newDescription,
|
||||
newTitle,
|
||||
newCopyOnSave,
|
||||
isTitleDuplicateConfirmed,
|
||||
onTitleDuplicate,
|
||||
returnToOrigin,
|
||||
}: OnSaveProps & { returnToOrigin: boolean }) {
|
||||
const prevTitle = savedMap.title;
|
||||
const prevDescription = savedMap.description;
|
||||
savedMap.title = newTitle;
|
||||
savedMap.description = newDescription;
|
||||
savedMap.copyOnSave = newCopyOnSave;
|
||||
|
||||
let id;
|
||||
try {
|
||||
savedMap.syncWithStore();
|
||||
id = await savedMap.save({
|
||||
confirmOverwrite: false,
|
||||
isTitleDuplicateConfirmed,
|
||||
onTitleDuplicate,
|
||||
});
|
||||
// id not returned when save fails because of duplicate title check.
|
||||
// return and let user confirm duplicate title.
|
||||
if (!id) {
|
||||
return {};
|
||||
}
|
||||
} catch (err) {
|
||||
getToasts().addDanger({
|
||||
title: i18n.translate('xpack.maps.topNav.saveErrorMessage', {
|
||||
defaultMessage: `Error saving '{title}'`,
|
||||
values: { title: savedMap.title },
|
||||
}),
|
||||
text: err.message,
|
||||
'data-test-subj': 'saveMapError',
|
||||
});
|
||||
// If the save wasn't successful, put the original values back.
|
||||
savedMap.title = prevTitle;
|
||||
savedMap.description = prevDescription;
|
||||
return { error: err };
|
||||
}
|
||||
|
||||
getToasts().addSuccess({
|
||||
title: i18n.translate('xpack.maps.topNav.saveSuccessMessage', {
|
||||
defaultMessage: `Saved '{title}'`,
|
||||
values: { title: savedMap.title },
|
||||
}),
|
||||
description: i18n.translate('xpack.maps.mapController.fullScreenDescription', {
|
||||
defaultMessage: `full screen`,
|
||||
'data-test-subj': 'saveMapSuccess',
|
||||
});
|
||||
|
||||
getCoreChrome().docTitle.change(savedMap.title);
|
||||
setBreadcrumbs();
|
||||
goToSpecifiedPath(`/map/${id}${window.location.hash}`);
|
||||
|
||||
const newlyCreated = newCopyOnSave || isNewMap;
|
||||
if (newlyCreated && !returnToOrigin) {
|
||||
cutOriginatingAppConnection();
|
||||
} else if (!!originatingApp && returnToOrigin) {
|
||||
if (newlyCreated && stateTransfer) {
|
||||
stateTransfer.navigateToWithEmbeddablePackage(originatingApp, {
|
||||
state: { id, type: MAP_SAVED_OBJECT_TYPE },
|
||||
});
|
||||
} else {
|
||||
navigateToApp(originatingApp);
|
||||
}
|
||||
}
|
||||
|
||||
return { id };
|
||||
}
|
||||
|
||||
if (hasSaveAndReturnConfig) {
|
||||
topNavConfigs.push({
|
||||
id: 'saveAndReturn',
|
||||
label: i18n.translate('xpack.maps.topNav.saveAndReturnButtonLabel', {
|
||||
defaultMessage: 'Save and return',
|
||||
}),
|
||||
testId: 'mapsFullScreenMode',
|
||||
run() {
|
||||
getCoreChrome().setIsVisible(false);
|
||||
enableFullScreen();
|
||||
emphasize: true,
|
||||
iconType: 'check',
|
||||
run: () => {
|
||||
onSave({
|
||||
newTitle: savedMap.title ? savedMap.title : '',
|
||||
newDescription: savedMap.description ? savedMap.description : '',
|
||||
newCopyOnSave: false,
|
||||
isTitleDuplicateConfirmed: false,
|
||||
returnToOrigin: true,
|
||||
onTitleDuplicate: () => {},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'inspect',
|
||||
label: i18n.translate('xpack.maps.mapController.openInspectorButtonLabel', {
|
||||
defaultMessage: `inspect`,
|
||||
testId: 'mapSaveAndReturnButton',
|
||||
});
|
||||
}
|
||||
|
||||
if (hasWritePermissions) {
|
||||
topNavConfigs.push({
|
||||
id: 'save',
|
||||
label: hasSaveAndReturnConfig
|
||||
? i18n.translate('xpack.maps.topNav.saveAsButtonLabel', {
|
||||
defaultMessage: 'Save as',
|
||||
})
|
||||
: i18n.translate('xpack.maps.topNav.saveMapButtonLabel', {
|
||||
defaultMessage: `save`,
|
||||
}),
|
||||
description: i18n.translate('xpack.maps.topNav.saveMapDescription', {
|
||||
defaultMessage: `Save map`,
|
||||
}),
|
||||
description: i18n.translate('xpack.maps.mapController.openInspectorDescription', {
|
||||
defaultMessage: `Open Inspector`,
|
||||
}),
|
||||
testId: 'openInspectorButton',
|
||||
run() {
|
||||
getInspector().open(inspectorAdapters, {});
|
||||
emphasize: !hasSaveAndReturnConfig,
|
||||
testId: 'mapSaveButton',
|
||||
disableButton() {
|
||||
return isSaveDisabled;
|
||||
},
|
||||
},
|
||||
tooltip() {
|
||||
if (isSaveDisabled) {
|
||||
return i18n.translate('xpack.maps.topNav.saveMapDisabledButtonTooltip', {
|
||||
defaultMessage: 'Confirm or Cancel your layer changes before saving',
|
||||
});
|
||||
}
|
||||
},
|
||||
run: () => {
|
||||
const saveModal = (
|
||||
<SavedObjectSaveModalOrigin
|
||||
originatingApp={originatingApp}
|
||||
onSave={onSave}
|
||||
onClose={() => {}}
|
||||
documentInfo={{
|
||||
description: savedMap.description,
|
||||
id: savedMap.id,
|
||||
title: savedMap.title,
|
||||
}}
|
||||
objectType={i18n.translate('xpack.maps.topNav.saveModalType', {
|
||||
defaultMessage: 'map',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
showSaveModal(saveModal, getCoreI18n().Context);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
topNavConfigs.push(
|
||||
{
|
||||
id: 'mapSettings',
|
||||
label: i18n.translate('xpack.maps.mapController.openSettingsButtonLabel', {
|
||||
label: i18n.translate('xpack.maps.topNav.openSettingsButtonLabel', {
|
||||
defaultMessage: `Map settings`,
|
||||
}),
|
||||
description: i18n.translate('xpack.maps.mapController.openSettingsDescription', {
|
||||
description: i18n.translate('xpack.maps.topNav.openSettingsDescription', {
|
||||
defaultMessage: `Open map settings`,
|
||||
}),
|
||||
testId: 'openSettingsButton',
|
||||
|
@ -88,107 +209,34 @@ export function getTopNavConfig({
|
|||
openMapSettings();
|
||||
},
|
||||
},
|
||||
...(getMapsCapabilities().save
|
||||
? [
|
||||
{
|
||||
id: 'save',
|
||||
label: i18n.translate('xpack.maps.mapController.saveMapButtonLabel', {
|
||||
defaultMessage: `save`,
|
||||
}),
|
||||
description: i18n.translate('xpack.maps.mapController.saveMapDescription', {
|
||||
defaultMessage: `Save map`,
|
||||
}),
|
||||
testId: 'mapSaveButton',
|
||||
disableButton() {
|
||||
return isSaveDisabled;
|
||||
},
|
||||
tooltip() {
|
||||
if (isSaveDisabled) {
|
||||
return i18n.translate('xpack.maps.mapController.saveMapDisabledButtonTooltip', {
|
||||
defaultMessage: 'Save or Cancel your layer changes before saving',
|
||||
});
|
||||
}
|
||||
},
|
||||
run: async () => {
|
||||
const onSave = ({
|
||||
newTitle,
|
||||
newCopyOnSave,
|
||||
isTitleDuplicateConfirmed,
|
||||
onTitleDuplicate,
|
||||
}: OnSaveProps) => {
|
||||
const currentTitle = savedMap.title;
|
||||
savedMap.title = newTitle;
|
||||
savedMap.copyOnSave = newCopyOnSave;
|
||||
const saveOptions: SavedObjectSaveOpts = {
|
||||
confirmOverwrite: false,
|
||||
isTitleDuplicateConfirmed,
|
||||
onTitleDuplicate,
|
||||
};
|
||||
return doSave(savedMap, saveOptions, closeFlyout, setBreadcrumbs).then(
|
||||
(response) => {
|
||||
// If the save wasn't successful, put the original values back.
|
||||
if (!response.id || response.error) {
|
||||
savedMap.title = currentTitle;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const saveModal = (
|
||||
<SavedObjectSaveModal
|
||||
onSave={onSave}
|
||||
onClose={() => {}}
|
||||
title={savedMap.title}
|
||||
showCopyOnSave={!!savedMap.id}
|
||||
objectType={MAP_SAVED_OBJECT_TYPE}
|
||||
showDescription={false}
|
||||
/>
|
||||
);
|
||||
showSaveModal(saveModal, getCoreI18n().Context);
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
}
|
||||
|
||||
async function doSave(
|
||||
savedMap: ISavedGisMap,
|
||||
saveOptions: SavedObjectSaveOpts,
|
||||
closeFlyout: () => void,
|
||||
setBreadcrumbs: () => void
|
||||
) {
|
||||
closeFlyout();
|
||||
savedMap.syncWithStore();
|
||||
let id;
|
||||
|
||||
try {
|
||||
id = await savedMap.save(saveOptions);
|
||||
getCoreChrome().docTitle.change(savedMap.title);
|
||||
} catch (err) {
|
||||
getToasts().addDanger({
|
||||
title: i18n.translate('xpack.maps.mapController.saveErrorMessage', {
|
||||
defaultMessage: `Error on saving '{title}'`,
|
||||
values: { title: savedMap.title },
|
||||
{
|
||||
id: 'inspect',
|
||||
label: i18n.translate('xpack.maps.topNav.openInspectorButtonLabel', {
|
||||
defaultMessage: `inspect`,
|
||||
}),
|
||||
text: err.message,
|
||||
'data-test-subj': 'saveMapError',
|
||||
});
|
||||
return { error: err };
|
||||
}
|
||||
|
||||
if (id) {
|
||||
goToSpecifiedPath(`/map/${id}${window.location.hash}`);
|
||||
setBreadcrumbs();
|
||||
|
||||
getToasts().addSuccess({
|
||||
title: i18n.translate('xpack.maps.mapController.saveSuccessMessage', {
|
||||
defaultMessage: `Saved '{title}'`,
|
||||
values: { title: savedMap.title },
|
||||
description: i18n.translate('xpack.maps.topNav.openInspectorDescription', {
|
||||
defaultMessage: `Open Inspector`,
|
||||
}),
|
||||
'data-test-subj': 'saveMapSuccess',
|
||||
});
|
||||
}
|
||||
return { id };
|
||||
testId: 'openInspectorButton',
|
||||
run() {
|
||||
getInspector().open(inspectorAdapters, {});
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'full-screen',
|
||||
label: i18n.translate('xpack.maps.topNav.fullScreenButtonLabel', {
|
||||
defaultMessage: `full screen`,
|
||||
}),
|
||||
description: i18n.translate('xpack.maps.topNav.fullScreenDescription', {
|
||||
defaultMessage: `full screen`,
|
||||
}),
|
||||
testId: 'mapsFullScreenMode',
|
||||
run() {
|
||||
getCoreChrome().setIsVisible(false);
|
||||
enableFullScreen();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return topNavConfigs;
|
||||
}
|
||||
|
|
|
@ -10409,18 +10409,7 @@
|
|||
"xpack.maps.layerWizardSelect.solutionsCategoryLabel": "ソリューション",
|
||||
"xpack.maps.loadMap.errorAttemptingToLoadSavedMap": "マップを読み込めません",
|
||||
"xpack.maps.map.initializeErrorTitle": "マップを初期化できません",
|
||||
"xpack.maps.mapController.fullScreenButtonLabel": "全画面",
|
||||
"xpack.maps.mapController.fullScreenDescription": "全画面",
|
||||
"xpack.maps.mapController.mapsBreadcrumbLabel": "マップ",
|
||||
"xpack.maps.mapController.openInspectorButtonLabel": "検査",
|
||||
"xpack.maps.mapController.openInspectorDescription": "インスペクターを開きます",
|
||||
"xpack.maps.mapController.openSettingsButtonLabel": "マップ設定",
|
||||
"xpack.maps.mapController.openSettingsDescription": "マップ設定を開く",
|
||||
"xpack.maps.mapController.saveErrorMessage": "「{title}」の保存中にエラーが発生しました",
|
||||
"xpack.maps.mapController.saveMapButtonLabel": "保存",
|
||||
"xpack.maps.mapController.saveMapDescription": "マップを保存",
|
||||
"xpack.maps.mapController.saveMapDisabledButtonTooltip": "保存する前に、レイヤーの変更を保存するか、キャンセルしてください",
|
||||
"xpack.maps.mapController.saveSuccessMessage": "「{title}」が保存されました",
|
||||
"xpack.maps.mapEmbeddableFactory.invalidLayerList": "不正な形式のレイヤーリストによりマップを読み込めません",
|
||||
"xpack.maps.mapEmbeddableFactory.invalidSavedObject": "不正な形式の保存済みオブジェクトによりマップを読み込めません",
|
||||
"xpack.maps.mapListing.advancedSettingsLinkText": "高度な設定",
|
||||
|
|
|
@ -10411,18 +10411,7 @@
|
|||
"xpack.maps.layerWizardSelect.solutionsCategoryLabel": "解决方案",
|
||||
"xpack.maps.loadMap.errorAttemptingToLoadSavedMap": "无法加载地图",
|
||||
"xpack.maps.map.initializeErrorTitle": "无法初始化地图",
|
||||
"xpack.maps.mapController.fullScreenButtonLabel": "全屏",
|
||||
"xpack.maps.mapController.fullScreenDescription": "全屏",
|
||||
"xpack.maps.mapController.mapsBreadcrumbLabel": "Maps",
|
||||
"xpack.maps.mapController.openInspectorButtonLabel": "检查",
|
||||
"xpack.maps.mapController.openInspectorDescription": "打开检查器",
|
||||
"xpack.maps.mapController.openSettingsButtonLabel": "地图设置",
|
||||
"xpack.maps.mapController.openSettingsDescription": "打开地图设置",
|
||||
"xpack.maps.mapController.saveErrorMessage": "保存 “{title}” 时出错",
|
||||
"xpack.maps.mapController.saveMapButtonLabel": "保存",
|
||||
"xpack.maps.mapController.saveMapDescription": "保存地图",
|
||||
"xpack.maps.mapController.saveMapDisabledButtonTooltip": "保存或在保存之前取消您的图层更改",
|
||||
"xpack.maps.mapController.saveSuccessMessage": "已保存“{title}”",
|
||||
"xpack.maps.mapEmbeddableFactory.invalidLayerList": "无法加载地图,图层列表格式不正确",
|
||||
"xpack.maps.mapEmbeddableFactory.invalidSavedObject": "无法加载地图,已保存对象格式错误",
|
||||
"xpack.maps.mapListing.advancedSettingsLinkText": "高级设置",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
export default function ({ loadTestFile }) {
|
||||
describe('embeddable', function () {
|
||||
loadTestFile(require.resolve('./save_and_return'));
|
||||
loadTestFile(require.resolve('./dashboard'));
|
||||
loadTestFile(require.resolve('./embeddable_state'));
|
||||
loadTestFile(require.resolve('./tooltip_filter_actions'));
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
export default function ({ getPageObjects, getService }) {
|
||||
const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'maps', 'visualize']);
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const dashboardPanelActions = getService('dashboardPanelActions');
|
||||
const dashboardVisualizations = getService('dashboardVisualizations');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
describe('save and return work flow', () => {
|
||||
describe('new map', () => {
|
||||
beforeEach(async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.clickCreateNewLink();
|
||||
await await dashboardVisualizations.ensureNewVisualizationDialogIsShowing();
|
||||
await PageObjects.visualize.clickMapsApp();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
});
|
||||
|
||||
describe('save', () => {
|
||||
it('should return to dashboard and add new panel', async () => {
|
||||
await PageObjects.maps.saveMap('map created from dashboard save and return');
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('save and uncheck return to origin switch', () => {
|
||||
it('should cut the originator and stay in maps application', async () => {
|
||||
await PageObjects.maps.saveMap(
|
||||
'map created from dashboard save and return with originator app cut',
|
||||
true
|
||||
);
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
await testSubjects.missingOrFail('mapSaveAndReturnButton');
|
||||
await testSubjects.existOrFail('mapSaveButton');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('edit existing map', () => {
|
||||
beforeEach(async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.loadSavedDashboard('map embeddable example');
|
||||
await PageObjects.dashboard.switchToEditMode();
|
||||
await dashboardPanelActions.editPanelByTitle('join example');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
});
|
||||
|
||||
describe('save and return', () => {
|
||||
it('should return to dashboard', async () => {
|
||||
await PageObjects.maps.clickSaveAndReturnButton();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('save as', () => {
|
||||
it('should return to dashboard and add new panel', async () => {
|
||||
await PageObjects.maps.saveMap('Clone of map embeddable example');
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('save as and uncheck return to origin switch', () => {
|
||||
it('should cut the originator and stay in maps application', async () => {
|
||||
await PageObjects.maps.saveMap('Clone 2 of map embeddable example', true);
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
await testSubjects.missingOrFail('mapSaveAndReturnButton');
|
||||
await testSubjects.existOrFail('mapSaveButton');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -139,12 +139,25 @@ export function GisPageProvider({ getService, getPageObjects }) {
|
|||
await renderable.waitForRender();
|
||||
}
|
||||
|
||||
async saveMap(name) {
|
||||
async saveMap(name, uncheckReturnToOriginModeSwitch = false) {
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await testSubjects.setValue('savedObjectTitle', name);
|
||||
if (uncheckReturnToOriginModeSwitch) {
|
||||
const redirectToOriginCheckboxExists = await testSubjects.exists(
|
||||
'returnToOriginModeSwitch'
|
||||
);
|
||||
if (!redirectToOriginCheckboxExists) {
|
||||
throw new Error('Unable to uncheck "returnToOriginModeSwitch", it does not exist.');
|
||||
}
|
||||
await testSubjects.setEuiSwitch('returnToOriginModeSwitch', 'uncheck');
|
||||
}
|
||||
await testSubjects.clickWhenNotDisabled('confirmSaveSavedObjectButton');
|
||||
}
|
||||
|
||||
async clickSaveAndReturnButton() {
|
||||
await testSubjects.click('mapSaveAndReturnButton');
|
||||
}
|
||||
|
||||
async expectMissingSaveButton() {
|
||||
await testSubjects.missingOrFail('mapSaveButton');
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue