Skip to content

Commit

Permalink
Made lens work with the attribute service copied from elastic#68719
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomThomson committed Jun 25, 2020
1 parent ef496ff commit 297dba0
Show file tree
Hide file tree
Showing 18 changed files with 291 additions and 148 deletions.
2 changes: 1 addition & 1 deletion src/plugins/embeddable/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export {
isRangeSelectTriggerContext,
isValueClickTriggerContext,
EmbeddableStateTransfer,
EmbeddableOriginatingAppState,
EmbeddableEditorState,
EmbeddablePackageState,
EmbeddableRenderer,
EmbeddableRendererProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test('redirects to app using state transfer', async () => {
const embeddable = new EditableEmbeddable({ id: '123', viewMode: ViewMode.EDIT }, true);
embeddable.getOutput = jest.fn(() => ({ editApp: 'ultraVisualize', editPath: '/123' }));
await action.execute({ embeddable });
expect(stateTransferMock.navigateToWithOriginatingApp).toHaveBeenCalledWith('ultraVisualize', {
expect(stateTransferMock.navigateToEditor).toHaveBeenCalledWith('ultraVisualize', {
path: '/123',
state: { originatingApp: 'superCoolCurrentApp' },
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class EditPanelAction implements Action<ActionContext> {
const appTarget = this.getAppTarget(context);
if (appTarget) {
if (this.stateTransfer && appTarget.state) {
await this.stateTransfer.navigateToWithOriginatingApp(appTarget.app, {
await this.stateTransfer.navigateToEditor(appTarget.app, {
path: appTarget.path,
state: appTarget.state,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('embeddable state transfer', () => {
});

it('can send an outgoing originating app state', async () => {
await stateTransfer.navigateToWithOriginatingApp(destinationApp, { state: { originatingApp } });
await stateTransfer.navigateToEditor(destinationApp, { state: { originatingApp } });
expect(application.navigateToApp).toHaveBeenCalledWith('superUltraVisualize', {
state: { originatingApp: 'superUltraTestDashboard' },
});
Expand All @@ -50,7 +50,7 @@ describe('embeddable state transfer', () => {
application.navigateToApp,
(historyMock as unknown) as ScopedHistory
);
await stateTransfer.navigateToWithOriginatingApp(destinationApp, {
await stateTransfer.navigateToEditor(destinationApp, {
state: { originatingApp },
appendToExistingState: true,
});
Expand Down Expand Up @@ -94,7 +94,7 @@ describe('embeddable state transfer', () => {
application.navigateToApp,
(historyMock as unknown) as ScopedHistory
);
const fetchedState = stateTransfer.getIncomingOriginatingApp();
const fetchedState = stateTransfer.getIncomingEditorState();
expect(fetchedState).toEqual({ originatingApp: 'extremeSportsKibana' });
});

Expand All @@ -104,7 +104,7 @@ describe('embeddable state transfer', () => {
application.navigateToApp,
(historyMock as unknown) as ScopedHistory
);
const fetchedState = stateTransfer.getIncomingOriginatingApp();
const fetchedState = stateTransfer.getIncomingEditorState();
expect(fetchedState).toBeUndefined();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import { cloneDeep } from 'lodash';
import { ScopedHistory, ApplicationStart } from '../../../../../core/public';
import {
EmbeddableOriginatingAppState,
isEmbeddableOriginatingAppState,
EmbeddableEditorState,
isEmbeddableEditorState,
EmbeddablePackageState,
isEmbeddablePackageState,
} from './types';
Expand All @@ -45,10 +45,10 @@ export class EmbeddableStateTransfer {
* @param history - the scoped history to fetch from
* @param options.keysToRemoveAfterFetch - an array of keys to be removed from the state after they are retrieved
*/
public getIncomingOriginatingApp(options?: {
public getIncomingEditorState(options?: {
keysToRemoveAfterFetch?: string[];
}): EmbeddableOriginatingAppState | undefined {
return this.getIncomingState<EmbeddableOriginatingAppState>(isEmbeddableOriginatingAppState, {
}): EmbeddableEditorState | undefined {
return this.getIncomingState<EmbeddableEditorState>(isEmbeddableEditorState, {
keysToRemoveAfterFetch: options?.keysToRemoveAfterFetch,
});
}
Expand All @@ -72,15 +72,15 @@ export class EmbeddableStateTransfer {
* A wrapper around the {@link ApplicationStart.navigateToApp} method which navigates to the specified appId
* with {@link EmbeddableOriginatingAppState | originating app state}
*/
public async navigateToWithOriginatingApp(
public async navigateToEditor(
appId: string,
options?: {
path?: string;
state: EmbeddableOriginatingAppState;
state: EmbeddableEditorState;
appendToExistingState?: boolean;
}
): Promise<void> {
await this.navigateToWithState<EmbeddableOriginatingAppState>(appId, options);
await this.navigateToWithState<EmbeddableEditorState>(appId, options);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/embeddable/public/lib/state_transfer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
*/

export { EmbeddableStateTransfer } from './embeddable_state_transfer';
export { EmbeddableOriginatingAppState, EmbeddablePackageState } from './types';
export { EmbeddableEditorState, EmbeddablePackageState } from './types';
24 changes: 17 additions & 7 deletions src/plugins/embeddable/public/lib/state_transfer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,43 @@
* under the License.
*/

import { EmbeddableInput } from '..';

/**
* Represents a state package that contains the last active app id.
* @public
*/
export interface EmbeddableOriginatingAppState {
export interface EmbeddableEditorState {
originatingApp: string;
byValueMode?: boolean;
}

export function isEmbeddableOriginatingAppState(
state: unknown
): state is EmbeddableOriginatingAppState {
export function isEmbeddableEditorState(state: unknown): state is EmbeddableEditorState {
return ensureFieldOfTypeExists('originatingApp', state, 'string');
}

/**
* Represents a state package that contains all fields necessary to create an embeddable in a container.
* @public
*/
export interface EmbeddablePackageState {
export interface EmbeddablePackageByReferenceState {
type: string;
id: string;
}

export interface EmbeddablePackageByValueState {
input: EmbeddableInput;
}

export type EmbeddablePackageState =
| EmbeddablePackageByReferenceState
| EmbeddablePackageByValueState;

export function isEmbeddablePackageState(state: unknown): state is EmbeddablePackageState {
return (
ensureFieldOfTypeExists('type', state, 'string') &&
ensureFieldOfTypeExists('id', state, 'string')
(ensureFieldOfTypeExists('type', state, 'string') &&
ensureFieldOfTypeExists('id', state, 'string')) ||
ensureFieldOfTypeExists('input', state, 'object')
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/plugins/embeddable/public/mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ export const createEmbeddablePanelMock = ({

export const createEmbeddableStateTransferMock = (): Partial<EmbeddableStateTransfer> => {
return {
getIncomingOriginatingApp: jest.fn(),
getIncomingEditorState: jest.fn(),
getIncomingEmbeddablePackage: jest.fn(),
navigateToWithOriginatingApp: jest.fn(),
navigateToEditor: jest.fn(),
navigateToWithEmbeddablePackage: jest.fn(),
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export class VisualizeEmbeddableFactory
showNewVisModal({
originatingApp: await this.getCurrentAppId(),
outsideVisualizeApp: true,
createByValue: true,
});
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ describe('NewVisModal', () => {
);
const visButton = wrapper.find('button[data-test-subj="visType-visWithAliasUrl"]');
visButton.simulate('click');
expect(stateTransfer.navigateToWithOriginatingApp).toBeCalledWith('otherApp', {
expect(stateTransfer.navigateToEditor).toBeCalledWith('otherApp', {
path: '#/aliasUrl',
state: { originatingApp: 'coolJestTestApp' },
});
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/visualizations/public/wizard/new_vis_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface TypeSelectionProps {
application: ApplicationStart;
outsideVisualizeApp?: boolean;
stateTransfer?: EmbeddableStateTransfer;
createByValue?: boolean;
originatingApp?: string;
}

Expand Down Expand Up @@ -172,9 +173,9 @@ class NewVisModal extends React.Component<TypeSelectionProps, TypeSelectionState

private navigate(appId: string, params: string) {
if (this.props.stateTransfer && this.props.originatingApp) {
this.props.stateTransfer.navigateToWithOriginatingApp(appId, {
this.props.stateTransfer.navigateToEditor(appId, {
path: params,
state: { originatingApp: this.props.originatingApp },
state: { originatingApp: this.props.originatingApp, byValueMode: this.props.createByValue },
});
} else {
this.props.application.navigateToApp(appId, {
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/visualizations/public/wizard/show_new_vis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface ShowNewVisModalParams {
onClose?: () => void;
originatingApp?: string;
outsideVisualizeApp?: boolean;
createByValue?: boolean;
}

/**
Expand All @@ -49,6 +50,7 @@ export function showNewVisModal({
onClose,
originatingApp,
outsideVisualizeApp,
createByValue,
}: ShowNewVisModalParams = {}) {
const container = document.createElement('div');
let isClosed = false;
Expand All @@ -69,6 +71,7 @@ export function showNewVisModal({
isOpen={true}
onClose={handleClose}
originatingApp={originatingApp}
createByValue={createByValue}
stateTransfer={getEmbeddable().getStateTransfer()}
outsideVisualizeApp={outsideVisualizeApp}
editorParams={editorParams}
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/lens/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ export function getBasePath() {
return `#/`;
}

export function getEditPath(id: string) {
return `#/edit/${encodeURIComponent(id)}`;
export function getEditPath(id: string | undefined) {
return id ? `#/edit/${encodeURIComponent(id)}` : '#/edit/value';
}
71 changes: 39 additions & 32 deletions x-pack/plugins/lens/public/app_plugin/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
SavedQuery,
UI_SETTINGS,
} from '../../../../../src/plugins/data/public';
import { EmbeddableEditorState } from '../../../../../src/plugins/embeddable/public';

interface State {
isLoading: boolean;
Expand All @@ -64,7 +65,7 @@ export function App({
docId,
docStorage,
redirectTo,
originatingApp,
embeddableEditorIncomingState,
navigation,
onAppLeave,
history,
Expand All @@ -77,7 +78,7 @@ export function App({
docId?: string;
docStorage: SavedObjectStore;
redirectTo: (id?: string, returnToOrigin?: boolean, newlyCreated?: boolean) => void;
originatingApp?: string | undefined;
embeddableEditorIncomingState?: EmbeddableEditorState;
onAppLeave: AppMountParameters['onAppLeave'];
history: History;
}) {
Expand Down Expand Up @@ -256,6 +257,7 @@ export function App({
if (!lastKnownDoc) {
return;
}

const [pinnedFilters, appFilters] = _.partition(
lastKnownDoc.state?.filters,
esFilters.isFilterPinned
Expand Down Expand Up @@ -297,32 +299,34 @@ export function App({
);

const newlyCreated: boolean = saveProps.newCopyOnSave || !lastKnownDoc?.id;
docStorage
.save(doc)
.then(({ id }) => {
// Prevents unnecessary network request and disables save button
const newDoc = { ...doc, id };
setState((s) => ({
...s,
isSaveModalVisible: false,
persistedDoc: newDoc,
lastKnownDoc: newDoc,
}));
if (docId !== id || saveProps.returnToOrigin) {
redirectTo(id, saveProps.returnToOrigin, newlyCreated);
}
})
.catch((e) => {
// eslint-disable-next-line no-console
console.dir(e);
trackUiEvent('save_failed');
core.notifications.toasts.addDanger(
i18n.translate('xpack.lens.app.docSavingError', {
defaultMessage: 'Error saving document',
})
);
setState((s) => ({ ...s, isSaveModalVisible: false }));
});
if (!embeddableEditorIncomingState?.byValueMode) {
docStorage
.save(doc)
.then(({ id }) => {
// Prevents unnecessary network request and disables save button
const newDoc = { ...doc, id };
setState((s) => ({
...s,
isSaveModalVisible: false,
persistedDoc: newDoc,
lastKnownDoc: newDoc,
}));
if (docId !== id || saveProps.returnToOrigin) {
redirectTo(id, saveProps.returnToOrigin, newlyCreated);
}
})
.catch((e) => {
// eslint-disable-next-line no-console
console.dir(e);
trackUiEvent('save_failed');
core.notifications.toasts.addDanger(
i18n.translate('xpack.lens.app.docSavingError', {
defaultMessage: 'Error saving document',
})
);
setState((s) => ({ ...s, isSaveModalVisible: false }));
});
}
};

const onError = useCallback(
Expand All @@ -349,7 +353,8 @@ export function App({
<div className="lnsApp__header">
<TopNavMenu
config={[
...(!!originatingApp && lastKnownDoc?.id
...((!!embeddableEditorIncomingState?.originatingApp && lastKnownDoc?.id) ||
embeddableEditorIncomingState?.byValueMode
? [
{
label: i18n.translate('xpack.lens.app.saveAndReturn', {
Expand All @@ -374,14 +379,16 @@ export function App({
: []),
{
label:
lastKnownDoc?.id && !!originatingApp
lastKnownDoc?.id ||
(embeddableEditorIncomingState?.byValueMode &&
!!embeddableEditorIncomingState?.originatingApp)
? i18n.translate('xpack.lens.app.saveAs', {
defaultMessage: 'Save as',
})
: i18n.translate('xpack.lens.app.save', {
defaultMessage: 'Save',
}),
emphasize: !originatingApp || !lastKnownDoc?.id,
emphasize: !embeddableEditorIncomingState?.originatingApp,
run: () => {
if (isSaveable && lastKnownDoc) {
setState((s) => ({ ...s, isSaveModalVisible: true }));
Expand Down Expand Up @@ -502,7 +509,7 @@ export function App({
</div>
{lastKnownDoc && state.isSaveModalVisible && (
<SavedObjectSaveModalOrigin
originatingApp={originatingApp}
originatingApp={embeddableEditorIncomingState?.originatingApp}
onSave={(props) => runSave(props)}
onClose={() => setState((s) => ({ ...s, isSaveModalVisible: false }))}
documentInfo={{
Expand Down
Loading

0 comments on commit 297dba0

Please sign in to comment.