mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
* [Time to Visualize] Add Discrete Library Option to Save Modal (#94589) * save modal UI and Redirect and save to library Co-authored-by: Poff Poffenberger <poffdeluxe@gmail.com> # Conflicts: # .github/CODEOWNERS # x-pack/test/functional/apps/lens/add_to_dashboard.ts * Update x-pack/test/functional/apps/lens/add_to_dashboard.ts * Delete CODEOWNERS
This commit is contained in:
parent
a1fdc06bd0
commit
15bd4b1889
12 changed files with 636 additions and 164 deletions
|
@ -30,7 +30,7 @@ export interface SaveModalDashboardProps {
|
|||
documentInfo: SaveModalDocumentInfo;
|
||||
objectType: string;
|
||||
onClose: () => void;
|
||||
onSave: (props: OnSaveProps & { dashboardId: string | null }) => void;
|
||||
onSave: (props: OnSaveProps & { dashboardId: string | null; addToLibrary: boolean }) => void;
|
||||
tagOptions?: React.ReactNode | ((state: SaveModalState) => React.ReactNode);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,9 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
const [dashboardOption, setDashboardOption] = useState<'new' | 'existing' | null>(
|
||||
documentId || disableDashboardOptions ? null : 'existing'
|
||||
);
|
||||
const [isAddToLibrarySelected, setAddToLibrary] = useState<boolean>(
|
||||
!initialCopyOnSave || disableDashboardOptions
|
||||
);
|
||||
const [selectedDashboard, setSelectedDashboard] = useState<{ id: string; name: string } | null>(
|
||||
null
|
||||
);
|
||||
|
@ -62,12 +65,13 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
onChange={(option) => {
|
||||
setDashboardOption(option);
|
||||
}}
|
||||
{...{ copyOnSave, documentId, dashboardOption }}
|
||||
{...{ copyOnSave, documentId, dashboardOption, setAddToLibrary, isAddToLibrarySelected }}
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
|
||||
const onCopyOnSaveChange = (newCopyOnSave: boolean) => {
|
||||
setAddToLibrary(true);
|
||||
setDashboardOption(null);
|
||||
setCopyOnSave(newCopyOnSave);
|
||||
};
|
||||
|
@ -85,7 +89,7 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
}
|
||||
}
|
||||
|
||||
props.onSave({ ...onSaveProps, dashboardId });
|
||||
props.onSave({ ...onSaveProps, dashboardId, addToLibrary: isAddToLibrarySelected });
|
||||
};
|
||||
|
||||
const saveLibraryLabel =
|
||||
|
@ -113,7 +117,7 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
|
|||
onSave={onModalSave}
|
||||
title={documentInfo.title}
|
||||
showCopyOnSave={documentId ? true : false}
|
||||
options={dashboardOption === null ? tagOptions : undefined} // Show tags when not adding to dashboard
|
||||
options={isAddToLibrarySelected ? tagOptions : undefined} // Show tags when not adding to dashboard
|
||||
description={documentInfo.description}
|
||||
showDescription={true}
|
||||
{...{
|
||||
|
|
|
@ -44,6 +44,7 @@ export function Example({
|
|||
hasDocumentId: boolean;
|
||||
} & StorybookParams) {
|
||||
const [dashboardOption, setDashboardOption] = useState<'new' | 'existing' | null>('existing');
|
||||
const [isAddToLibrarySelected, setAddToLibrary] = useState(false);
|
||||
|
||||
return (
|
||||
<SaveModalDashboardSelector
|
||||
|
@ -52,6 +53,8 @@ export function Example({
|
|||
dashboardOption={dashboardOption}
|
||||
copyOnSave={copyOnSave}
|
||||
documentId={hasDocumentId ? 'abc' : undefined}
|
||||
isAddToLibrarySelected={isAddToLibrarySelected}
|
||||
setAddToLibrary={setAddToLibrary}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
EuiIconTip,
|
||||
EuiPanel,
|
||||
EuiSpacer,
|
||||
EuiCheckbox,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { DashboardPicker, DashboardPickerProps } from './dashboard_picker';
|
||||
|
@ -29,24 +30,105 @@ export interface SaveModalDashboardSelectorProps {
|
|||
copyOnSave: boolean;
|
||||
documentId?: string;
|
||||
onSelectDashboard: DashboardPickerProps['onChange'];
|
||||
|
||||
setAddToLibrary: (selected: boolean) => void;
|
||||
isAddToLibrarySelected: boolean;
|
||||
dashboardOption: 'new' | 'existing' | null;
|
||||
onChange: (dashboardOption: 'new' | 'existing' | null) => void;
|
||||
}
|
||||
|
||||
export function SaveModalDashboardSelector(props: SaveModalDashboardSelectorProps) {
|
||||
const { documentId, onSelectDashboard, dashboardOption, onChange, copyOnSave } = props;
|
||||
const {
|
||||
documentId,
|
||||
onSelectDashboard,
|
||||
setAddToLibrary,
|
||||
isAddToLibrarySelected,
|
||||
dashboardOption,
|
||||
onChange,
|
||||
copyOnSave,
|
||||
} = props;
|
||||
const isDisabled = !copyOnSave && !!documentId;
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFormRow
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="presentationUtil.saveModalDashboard.addToDashboardLabel"
|
||||
defaultMessage="Add to dashboard"
|
||||
/>
|
||||
}
|
||||
hasChildLabel={false}
|
||||
>
|
||||
<>
|
||||
<EuiPanel color="subdued" hasShadow={false} data-test-subj="add-to-dashboard-options">
|
||||
<div>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'existing'}
|
||||
id="existing-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.existingDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'Existing',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('existing')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<div className="savAddDashboard__searchDashboards">
|
||||
<DashboardPicker
|
||||
isDisabled={dashboardOption !== 'existing'}
|
||||
onChange={onSelectDashboard}
|
||||
/>
|
||||
</div>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'new'}
|
||||
id="new-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.newDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'New',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('new')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === null}
|
||||
id="add-to-library-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.noDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'None',
|
||||
}
|
||||
)}
|
||||
onChange={() => {
|
||||
setAddToLibrary(true);
|
||||
onChange(null);
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
</EuiPanel>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<FormattedMessage
|
||||
id="presentationUtil.saveModalDashboard.addToDashboardLabel"
|
||||
defaultMessage="Add to dashboard"
|
||||
<EuiFlexItem grow={false} data-test-subj="add-to-library-checkbox">
|
||||
<EuiCheckbox
|
||||
id="add-to-library-checkbox"
|
||||
label={i18n.translate('presentationUtil.saveModalDashboard.libraryOptionLabel', {
|
||||
defaultMessage: 'Add to library',
|
||||
})}
|
||||
checked={isAddToLibrarySelected}
|
||||
disabled={dashboardOption === null || isDisabled}
|
||||
onChange={(event) => setAddToLibrary(event.target.checked)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -55,67 +137,13 @@ export function SaveModalDashboardSelector(props: SaveModalDashboardSelectorProp
|
|||
content={
|
||||
<FormattedMessage
|
||||
id="presentationUtil.saveModalDashboard.dashboardInfoTooltip"
|
||||
defaultMessage="Items added to a dashboard will not appear in the library and must be edited from the dashboard."
|
||||
defaultMessage="items added to the Visualize Library are available to all dashboards. Edits to a library item appear everywhere it is used."
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
hasChildLabel={false}
|
||||
>
|
||||
<EuiPanel color="subdued" hasShadow={false} data-test-subj="add-to-dashboard-options">
|
||||
<div>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'existing'}
|
||||
id="existing-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.existingDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'Existing',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('existing')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<div className="savAddDashboard__searchDashboards">
|
||||
<DashboardPicker
|
||||
isDisabled={dashboardOption !== 'existing'}
|
||||
onChange={onSelectDashboard}
|
||||
/>
|
||||
</div>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === 'new'}
|
||||
id="new-dashboard-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate(
|
||||
'presentationUtil.saveModalDashboard.newDashboardOptionLabel',
|
||||
{
|
||||
defaultMessage: 'New',
|
||||
}
|
||||
)}
|
||||
onChange={() => onChange('new')}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
<EuiRadio
|
||||
checked={dashboardOption === null}
|
||||
id="add-to-library-option"
|
||||
name="dashboard-option"
|
||||
label={i18n.translate('presentationUtil.saveModalDashboard.libraryOptionLabel', {
|
||||
defaultMessage: 'No dashboard, but add to library',
|
||||
})}
|
||||
onChange={() => onChange(null)}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
</div>
|
||||
</EuiPanel>
|
||||
</>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -93,7 +93,7 @@ export const getTopNavConfig = (
|
|||
/**
|
||||
* Called when the user clicks "Save" button.
|
||||
*/
|
||||
async function doSave(saveOptions: SavedObjectSaveOpts) {
|
||||
async function doSave(saveOptions: SavedObjectSaveOpts & { dashboardId?: string }) {
|
||||
const newlyCreated = !Boolean(savedVis.id) || savedVis.copyOnSave;
|
||||
// vis.title was not bound and it's needed to reflect title into visState
|
||||
stateContainer.transitions.setVis({
|
||||
|
@ -118,7 +118,7 @@ export const getTopNavConfig = (
|
|||
'data-test-subj': 'saveVisualizationSuccess',
|
||||
});
|
||||
|
||||
if (originatingApp && saveOptions.returnToOrigin) {
|
||||
if ((originatingApp && saveOptions.returnToOrigin) || saveOptions.dashboardId) {
|
||||
if (!embeddableId) {
|
||||
const appPath = `${VisualizeConstants.EDIT_PATH}/${encodeURIComponent(id)}`;
|
||||
|
||||
|
@ -127,16 +127,26 @@ export const getTopNavConfig = (
|
|||
setActiveUrl(appPath);
|
||||
}
|
||||
|
||||
const app = originatingApp || 'dashboards';
|
||||
|
||||
let path;
|
||||
if (saveOptions.dashboardId) {
|
||||
path =
|
||||
saveOptions.dashboardId === 'new' ? '#/create' : `#/view/${saveOptions.dashboardId}`;
|
||||
}
|
||||
|
||||
if (newlyCreated && stateTransfer) {
|
||||
stateTransfer.navigateToWithEmbeddablePackage(originatingApp, {
|
||||
stateTransfer.navigateToWithEmbeddablePackage(app, {
|
||||
state: {
|
||||
type: VISUALIZE_EMBEDDABLE_TYPE,
|
||||
input: { savedObjectId: id },
|
||||
embeddableId,
|
||||
},
|
||||
path,
|
||||
});
|
||||
} else {
|
||||
application.navigateToApp(originatingApp);
|
||||
// TODO: need the same thing here?
|
||||
application.navigateToApp(app, { path });
|
||||
}
|
||||
} else {
|
||||
if (setOriginatingApp && originatingApp && newlyCreated) {
|
||||
|
@ -321,7 +331,11 @@ export const getTopNavConfig = (
|
|||
newDescription,
|
||||
returnToOrigin,
|
||||
dashboardId,
|
||||
}: OnSaveProps & { returnToOrigin?: boolean } & { dashboardId?: string | null }) => {
|
||||
addToLibrary,
|
||||
}: OnSaveProps & { returnToOrigin?: boolean } & {
|
||||
dashboardId?: string | null;
|
||||
addToLibrary?: boolean;
|
||||
}) => {
|
||||
const currentTitle = savedVis.title;
|
||||
savedVis.title = newTitle;
|
||||
embeddableHandler.updateInput({ title: newTitle });
|
||||
|
@ -337,9 +351,12 @@ export const getTopNavConfig = (
|
|||
isTitleDuplicateConfirmed,
|
||||
onTitleDuplicate,
|
||||
returnToOrigin,
|
||||
dashboardId: !!dashboardId ? dashboardId : undefined,
|
||||
};
|
||||
|
||||
if (dashboardId) {
|
||||
// If we're adding to a dashboard and not saving to library,
|
||||
// we'll want to use a by-value operation
|
||||
if (dashboardId && !addToLibrary) {
|
||||
const appPath = `${VisualizeConstants.LANDING_PAGE_PATH}`;
|
||||
|
||||
// Manually insert a new url so the back button will open the saved visualization.
|
||||
|
@ -369,6 +386,8 @@ export const getTopNavConfig = (
|
|||
return { id: true };
|
||||
}
|
||||
|
||||
// We're adding the viz to a library so we need to save it and then
|
||||
// add to a dashboard if necessary
|
||||
const response = await doSave(saveOptions);
|
||||
// If the save wasn't successful, put the original values back.
|
||||
if (!response.id || response.error) {
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
]);
|
||||
|
||||
describe('Add to Dashboard', function describeIndexTests() {
|
||||
it('adding a new metric to a new dashboard', async function () {
|
||||
it('adding a new metric to a new dashboard by value', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
|
@ -36,6 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
@ -43,10 +44,39 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists('My New Vis 1');
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a existing metric to a new dashboard', async function () {
|
||||
it('adding a new metric to a new dashboard by reference', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My Saved New Vis 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My Saved New Vis 1'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a existing metric to a new dashboard by value', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
|
@ -57,6 +87,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
@ -68,6 +99,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1 Copy', {
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
@ -75,10 +107,85 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Vis 1 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a new metric to an existing dashboard', async function () {
|
||||
it('adding a existing metric to a new dashboard by reference', async function () {
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('Another New Vis 1', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// All the options should be disabled
|
||||
await PageObjects.timeToVisualize.ensureDashboardOptionsAreDisabled();
|
||||
|
||||
// Save a new copy of this viz to a new dashboard
|
||||
await PageObjects.timeToVisualize.saveFromModal('Another New Vis 1 Copy', {
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Another New Vis 1 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('adding a new metric to an existing dashboard by value', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations(['Visualization AreaChart']);
|
||||
await PageObjects.dashboard.saveDashboard('My Excellent Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Excellent Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Excellent Dashboard',
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists('My New Vis 2');
|
||||
expect(isLinked).to.be(false);
|
||||
});
|
||||
|
||||
it('adding a new metric to an existing dashboard by reference', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
@ -94,18 +201,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
|
||||
await PageObjects.timeToVisualize.saveFromModal('My Saved New Vis 2', {
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Wonderful Dashboard',
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My Saved New Vis 2'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
});
|
||||
|
||||
it('adding a existing metric to an existing dashboard', async function () {
|
||||
it('adding a existing metric to an existing dashboard by value', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
@ -124,6 +237,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
@ -136,12 +250,64 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Very Cool Dashboard',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Vis 2 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
});
|
||||
|
||||
it('adding a existing metric to an existing dashboard by reference', async function () {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations(['Visualization AreaChart']);
|
||||
await PageObjects.dashboard.saveDashboard('My Very Neat Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Very Neat Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.navigateToNewAggBasedVisualization();
|
||||
await PageObjects.visualize.clickMetric();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// Save this new viz to library
|
||||
await PageObjects.timeToVisualize.saveFromModal('Neat Saved Vis 2', {
|
||||
addToDashboard: null,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await testSubjects.click('visualizeSaveButton');
|
||||
|
||||
// All the options should be disabled
|
||||
await PageObjects.timeToVisualize.ensureDashboardOptionsAreDisabled();
|
||||
|
||||
// Save a new copy of this viz to an existing dashboard
|
||||
await PageObjects.timeToVisualize.saveFromModal('Neat Saved Vis 2 Copy', {
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Very Neat Dashboard',
|
||||
saveAsNew: true,
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.metricValuesExist(['14,004']);
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Neat Saved Vis 2 Copy'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { FtrProviderContext } from '../ftr_provider_context';
|
|||
|
||||
interface SaveModalArgs {
|
||||
addToDashboard?: 'new' | 'existing' | null;
|
||||
saveToLibrary?: boolean;
|
||||
dashboardId?: string;
|
||||
saveAsNew?: boolean;
|
||||
redirectToOrigin?: boolean;
|
||||
|
@ -35,7 +36,9 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
const dashboardSelector = await testSubjects.find('add-to-dashboard-options');
|
||||
await dashboardSelector.findByCssSelector(`input[id="new-dashboard-option"]:disabled`);
|
||||
await dashboardSelector.findByCssSelector(`input[id="existing-dashboard-option"]:disabled`);
|
||||
await dashboardSelector.findByCssSelector(`input[id="add-to-library-option"]:disabled`);
|
||||
|
||||
const librarySelector = await testSubjects.find('add-to-library-checkbox');
|
||||
await librarySelector.findByCssSelector(`input[id="add-to-library-checkbox"]:disabled`);
|
||||
}
|
||||
|
||||
public async resetNewDashboard() {
|
||||
|
@ -46,7 +49,13 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
|
||||
public async setSaveModalValues(
|
||||
vizName: string,
|
||||
{ saveAsNew, redirectToOrigin, addToDashboard, dashboardId }: SaveModalArgs = {}
|
||||
{
|
||||
saveAsNew,
|
||||
redirectToOrigin,
|
||||
addToDashboard,
|
||||
dashboardId,
|
||||
saveToLibrary,
|
||||
}: SaveModalArgs = {}
|
||||
) {
|
||||
await testSubjects.setValue('savedObjectTitle', vizName);
|
||||
|
||||
|
@ -57,13 +66,6 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
await testSubjects.setEuiSwitch('saveAsNewCheckbox', state);
|
||||
}
|
||||
|
||||
const hasRedirectToOrigin = await testSubjects.exists('returnToOriginModeSwitch');
|
||||
if (hasRedirectToOrigin && redirectToOrigin !== undefined) {
|
||||
const state = redirectToOrigin ? 'check' : 'uncheck';
|
||||
log.debug('redirect to origin checkbox exists. Setting its state to', state);
|
||||
await testSubjects.setEuiSwitch('returnToOriginModeSwitch', state);
|
||||
}
|
||||
|
||||
const hasDashboardSelector = await testSubjects.exists('add-to-dashboard-options');
|
||||
if (hasDashboardSelector && addToDashboard !== undefined) {
|
||||
let option: DashboardPickerOption = 'add-to-library-option';
|
||||
|
@ -80,6 +82,40 @@ export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrP
|
|||
await find.clickByButtonText(dashboardId);
|
||||
}
|
||||
}
|
||||
|
||||
const hasSaveToLibrary = await testSubjects.exists('add-to-library-checkbox');
|
||||
if (hasSaveToLibrary && saveToLibrary !== undefined) {
|
||||
const libraryCheckbox = await find.byCssSelector('#add-to-library-checkbox');
|
||||
const isChecked = await libraryCheckbox.isSelected();
|
||||
const needsClick = isChecked !== saveToLibrary;
|
||||
const state = saveToLibrary ? 'check' : 'uncheck';
|
||||
|
||||
log.debug('save to library checkbox exists. Setting its state to', state);
|
||||
if (needsClick) {
|
||||
const selector = await testSubjects.find('add-to-library-checkbox');
|
||||
const label = await selector.findByCssSelector(`label[for="add-to-library-checkbox"]`);
|
||||
await label.click();
|
||||
}
|
||||
}
|
||||
|
||||
const hasRedirectToOrigin = await testSubjects.exists('returnToOriginModeSwitch');
|
||||
if (hasRedirectToOrigin && redirectToOrigin !== undefined) {
|
||||
const state = redirectToOrigin ? 'check' : 'uncheck';
|
||||
log.debug('redirect to origin checkbox exists. Setting its state to', state);
|
||||
await testSubjects.setEuiSwitch('returnToOriginModeSwitch', state);
|
||||
}
|
||||
}
|
||||
|
||||
public async libraryNotificationExists(panelTitle: string) {
|
||||
log.debug('searching for library modal on panel:', panelTitle);
|
||||
const panel = await testSubjects.find(
|
||||
`embeddablePanelHeading-${panelTitle.replace(/ /g, '')}`
|
||||
);
|
||||
const libraryActionExists = await testSubjects.descendantExists(
|
||||
'embeddablePanelNotification-ACTION_LIBRARY_NOTIFICATION',
|
||||
panel
|
||||
);
|
||||
return libraryActionExists;
|
||||
}
|
||||
|
||||
public async saveFromModal(
|
||||
|
|
|
@ -86,7 +86,7 @@ export const SaveModal = (props: Props) => {
|
|||
savedObjectsTagging={savedObjectsTagging}
|
||||
initialTags={tagsIds}
|
||||
onSave={(saveProps) => {
|
||||
const saveToLibrary = saveProps.dashboardId === null;
|
||||
const saveToLibrary = Boolean(saveProps.addToLibrary);
|
||||
onSave(saveProps, { saveToLibrary });
|
||||
}}
|
||||
onClose={onClose}
|
||||
|
|
|
@ -16,6 +16,7 @@ import { SavedObjectTaggingPluginStart } from '../../../saved_objects_tagging/pu
|
|||
export type DashboardSaveProps = OnSaveProps & {
|
||||
returnToOrigin: boolean;
|
||||
dashboardId?: string | null;
|
||||
addToLibrary?: boolean;
|
||||
newTags?: string[];
|
||||
};
|
||||
|
||||
|
|
|
@ -145,7 +145,11 @@ export function getTopNavConfig({
|
|||
|
||||
const saveModalProps = {
|
||||
onSave: async (
|
||||
props: OnSaveProps & { returnToOrigin?: boolean; dashboardId?: string | null }
|
||||
props: OnSaveProps & {
|
||||
returnToOrigin?: boolean;
|
||||
dashboardId?: string | null;
|
||||
addToLibrary?: boolean;
|
||||
}
|
||||
) => {
|
||||
try {
|
||||
await checkForDuplicateTitle(
|
||||
|
@ -172,7 +176,7 @@ export function getTopNavConfig({
|
|||
await savedMap.save({
|
||||
...props,
|
||||
newTags: selectedTags,
|
||||
saveByReference: !props.dashboardId,
|
||||
saveByReference: Boolean(props.addToLibrary),
|
||||
});
|
||||
// showSaveModal wrapper requires onSave to return an object with an id to close the modal after successful save
|
||||
return { id: 'id' };
|
||||
|
|
|
@ -23,28 +23,57 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const testSubjects = getService('testSubjects');
|
||||
const security = getService('security');
|
||||
|
||||
const createNewLens = async () => {
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
|
||||
operation: 'avg',
|
||||
field: 'bytes',
|
||||
});
|
||||
|
||||
await PageObjects.lens.switchToVisualization('lnsMetric');
|
||||
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
};
|
||||
|
||||
const createAndSaveDashboard = async (dashboardName: string) => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.clickOpenAddPanel();
|
||||
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
|
||||
await find.clickByButtonText('lnsXYvis');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard(dashboardName);
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1);
|
||||
};
|
||||
|
||||
const loadExistingLens = async () => {
|
||||
await PageObjects.visualize.gotoVisualizationLandingPage();
|
||||
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
};
|
||||
|
||||
describe('lens add-to-dashboards tests', () => {
|
||||
it('should allow new lens vizs be added to a new dashboard', async () => {
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
|
||||
operation: 'avg',
|
||||
field: 'bytes',
|
||||
});
|
||||
|
||||
await PageObjects.lens.switchToVisualization('lnsMetric');
|
||||
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
|
||||
await PageObjects.lens.save('New Lens from Modal', false, false, 'new');
|
||||
it('should allow new lens to be added by value to a new dashboard', async () => {
|
||||
await createNewLens();
|
||||
await PageObjects.lens.save('New Lens from Modal', false, false, false, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New Lens from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
@ -52,18 +81,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing lens vizs be added to a new dashboard', async () => {
|
||||
await PageObjects.visualize.gotoVisualizationLandingPage();
|
||||
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
|
||||
await PageObjects.lens.save('Artistpreviouslyknownaslens Copy', true, false, 'new');
|
||||
it('should allow existing lens be added by value to a new dashboard', async () => {
|
||||
await loadExistingLens();
|
||||
await PageObjects.lens.save('Artistpreviouslyknownaslens Copy', true, false, false, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
@ -71,38 +99,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new lens vizs be added to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.clickOpenAddPanel();
|
||||
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
|
||||
await find.clickByButtonText('lnsXYvis');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Very Cool Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Very Cool Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
|
||||
operation: 'avg',
|
||||
field: 'bytes',
|
||||
});
|
||||
|
||||
await PageObjects.lens.switchToVisualization('lnsMetric');
|
||||
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
it('should allow new lens be added by value to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Very Cool Dashboard');
|
||||
await createNewLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'New Lens from Modal',
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
'existing',
|
||||
'My Very Cool Dashboard'
|
||||
);
|
||||
|
@ -110,34 +115,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New Lens from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
});
|
||||
|
||||
it('should allow existing lens vizs be added to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardAddPanel.clickOpenAddPanel();
|
||||
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
|
||||
await find.clickByButtonText('lnsXYvis');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Wonderful Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Wonderful Dashboard', 1);
|
||||
|
||||
await PageObjects.visualize.gotoVisualizationLandingPage();
|
||||
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
it('should allow existing lens be added by value to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Wonderful Dashboard');
|
||||
await loadExistingLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'Artistpreviouslyknownaslens Copy',
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
'existing',
|
||||
'My Wonderful Dashboard'
|
||||
);
|
||||
|
@ -145,6 +140,96 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens Copy'
|
||||
);
|
||||
expect(isLinked).to.be(false);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
});
|
||||
|
||||
it('should allow new lens to be added by reference to a new dashboard', async () => {
|
||||
await createNewLens();
|
||||
await PageObjects.lens.save('New by ref Lens from Modal', false, false, true, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New by ref Lens from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing lens be added by reference to a new dashboard', async () => {
|
||||
await loadExistingLens();
|
||||
await PageObjects.lens.save('Artistpreviouslyknownaslens by ref', true, false, true, 'new');
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens by ref'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new lens be added by reference to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Very Cool Dashboard 2');
|
||||
await createNewLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'New Lens by ref from Modal',
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
'existing',
|
||||
'My Very Cool Dashboard 2'
|
||||
);
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'New Lens by ref from Modal'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
});
|
||||
|
||||
it('should allow existing lens be added by reference to an existing dashboard', async () => {
|
||||
await createAndSaveDashboard('My Wonderful Dashboard 2');
|
||||
await loadExistingLens();
|
||||
|
||||
await PageObjects.lens.save(
|
||||
'Artistpreviouslyknownaslens by ref 2',
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
'existing',
|
||||
'My Wonderful Dashboard 2'
|
||||
);
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
|
||||
const isLinked = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'Artistpreviouslyknownaslens by ref 2'
|
||||
);
|
||||
expect(isLinked).to.be(true);
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(2);
|
||||
|
|
|
@ -39,27 +39,33 @@ export default function ({ getPageObjects, getService }) {
|
|||
await security.testUser.restoreDefaults();
|
||||
});
|
||||
|
||||
it('should allow new map be added to a new dashboard', async () => {
|
||||
it('should allow new map be added by value to a new dashboard', async () => {
|
||||
await PageObjects.maps.openNewMap();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('map 1', { addToDashboard: 'new' });
|
||||
await PageObjects.timeToVisualize.saveFromModal('map 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: false,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists('map 1');
|
||||
expect(isInLibrary).to.be(false);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing maps be added to a new dashboard', async () => {
|
||||
it('should allow existing maps be added by value to a new dashboard', async () => {
|
||||
await PageObjects.maps.loadSavedMap('document example');
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy', {
|
||||
saveToLibrary: false,
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
});
|
||||
|
@ -69,10 +75,14 @@ export default function ({ getPageObjects, getService }) {
|
|||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy'
|
||||
);
|
||||
expect(isInLibrary).to.be(false);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new map be added to an existing dashboard', async () => {
|
||||
it('should allow new map be added by value to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
|
@ -86,6 +96,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Map 2', {
|
||||
saveToLibrary: false,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Very Cool Dashboard',
|
||||
});
|
||||
|
@ -94,9 +105,14 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Map 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(false);
|
||||
});
|
||||
|
||||
it('should allow existing maps be added to an existing dashboard', async () => {
|
||||
it('should allow existing maps be added by value to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
|
@ -108,6 +124,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy 2', {
|
||||
saveToLibrary: false,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Wonderful Dashboard',
|
||||
saveAsNew: true,
|
||||
|
@ -117,6 +134,113 @@ export default function ({ getPageObjects, getService }) {
|
|||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(false);
|
||||
});
|
||||
|
||||
it('should allow new map be added by reference to a new dashboard', async () => {
|
||||
await PageObjects.maps.openNewMap();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('map 1', {
|
||||
addToDashboard: 'new',
|
||||
saveToLibrary: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists('map 1');
|
||||
expect(isInLibrary).to.be(true);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow existing maps be added by reference to a new dashboard', async () => {
|
||||
await PageObjects.maps.loadSavedMap('document example');
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy', {
|
||||
saveToLibrary: true,
|
||||
addToDashboard: 'new',
|
||||
saveAsNew: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy'
|
||||
);
|
||||
expect(isInLibrary).to.be(true);
|
||||
await PageObjects.timeToVisualize.resetNewDashboard();
|
||||
});
|
||||
|
||||
it('should allow new map be added by reference to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Super Cool Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Super Cool Dashboard', 1);
|
||||
|
||||
await PageObjects.maps.openNewMap();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.maps.waitForLayersToLoad();
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('My New Map 2', {
|
||||
saveToLibrary: true,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Super Cool Dashboard',
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'My New Map 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(true);
|
||||
});
|
||||
|
||||
it('should allow existing maps be added by reference to an existing dashboard', async () => {
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
await PageObjects.dashboard.saveDashboard('My Amazing Dashboard');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await listingTable.searchAndExpectItemsCount('dashboard', 'My Amazing Dashboard', 1);
|
||||
|
||||
await PageObjects.maps.loadSavedMap('document example');
|
||||
|
||||
await testSubjects.click('mapSaveButton');
|
||||
await PageObjects.timeToVisualize.saveFromModal('document example copy 2', {
|
||||
saveToLibrary: true,
|
||||
addToDashboard: 'existing',
|
||||
dashboardId: 'My Amazing Dashboard',
|
||||
saveAsNew: true,
|
||||
});
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
|
||||
const isInLibrary = await PageObjects.timeToVisualize.libraryNotificationExists(
|
||||
'document example copy 2'
|
||||
);
|
||||
expect(isInLibrary).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -349,6 +349,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
|
|||
title: string,
|
||||
saveAsNew?: boolean,
|
||||
redirectToOrigin?: boolean,
|
||||
saveToLibrary?: boolean,
|
||||
addToDashboard?: 'new' | 'existing' | null,
|
||||
dashboardId?: string
|
||||
) {
|
||||
|
@ -360,6 +361,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
|
|||
redirectToOrigin,
|
||||
addToDashboard: addToDashboard ? addToDashboard : null,
|
||||
dashboardId,
|
||||
saveToLibrary,
|
||||
});
|
||||
|
||||
await testSubjects.click('confirmSaveSavedObjectButton');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue