[Reporting/Visualization] Migrate Visualize to V2 reporting (#110206)
* added initial version of locator * removed unused params and added jest test * updated functional test to expect PDF reports to be available when vis is new * fix TS: remove unkown field * added some docs and removed unused code * AggsConfigOption -> AggsConfigSerialized * moved locator to common * fixed building of "create" path and updated test snapshots * updated import * update encoding behaviour * added time range from timefilter to locator params request * add index pattern and search id to URL params * reading index pattern from search source if it is there for the locator * remove "type" from locator params, update comments and test * removed duplicate identifier * remove unused type Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
d4c03eb9b4
commit
1f06cafa19
|
@ -78,7 +78,7 @@ export const getStats = async (
|
|||
|
||||
const doTelemetry = ({ params }: SavedVisState) => {
|
||||
try {
|
||||
const spec = parse(params.spec, { legacyRoot: false });
|
||||
const spec = parse(params.spec as string, { legacyRoot: false });
|
||||
|
||||
if (spec) {
|
||||
shouldPublishTelemetry = true;
|
||||
|
|
|
@ -7,18 +7,20 @@
|
|||
*/
|
||||
|
||||
import { SavedObjectAttributes } from 'kibana/server';
|
||||
import { AggConfigOptions } from 'src/plugins/data/common';
|
||||
import type { SerializableRecord } from '@kbn/utility-types';
|
||||
import { AggConfigSerialized } from 'src/plugins/data/common';
|
||||
|
||||
export interface VisParams {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface SavedVisState<TVisParams = VisParams> {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
export type SavedVisState<TVisParams = SerializableRecord> = {
|
||||
title: string;
|
||||
type: string;
|
||||
params: TVisParams;
|
||||
aggs: AggConfigOptions[];
|
||||
}
|
||||
aggs: AggConfigSerialized[];
|
||||
};
|
||||
|
||||
export interface VisualizationSavedObjectAttributes extends SavedObjectAttributes {
|
||||
description: string;
|
||||
|
|
|
@ -115,7 +115,7 @@ describe('injectReferences', () => {
|
|||
});
|
||||
|
||||
test('injects references into context', () => {
|
||||
const context = {
|
||||
const context = ({
|
||||
id: '1',
|
||||
title: 'test',
|
||||
savedSearchRefName: 'search_0',
|
||||
|
@ -133,7 +133,7 @@ describe('injectReferences', () => {
|
|||
],
|
||||
},
|
||||
} as unknown) as SavedVisState,
|
||||
} as VisSavedObject;
|
||||
} as unknown) as VisSavedObject;
|
||||
const references = [
|
||||
{
|
||||
name: 'search_0',
|
||||
|
@ -182,7 +182,7 @@ describe('injectReferences', () => {
|
|||
});
|
||||
|
||||
test(`fails when it can't find the index pattern reference in the array`, () => {
|
||||
const context = {
|
||||
const context = ({
|
||||
id: '1',
|
||||
title: 'test',
|
||||
visState: ({
|
||||
|
@ -196,7 +196,7 @@ describe('injectReferences', () => {
|
|||
],
|
||||
},
|
||||
} as unknown) as SavedVisState,
|
||||
} as VisSavedObject;
|
||||
} as unknown) as VisSavedObject;
|
||||
expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Could not find index pattern reference \\"control_0_index_pattern\\""`
|
||||
);
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
import { SavedObject } from '../../../plugins/saved_objects/public';
|
||||
import {
|
||||
AggConfigOptions,
|
||||
IAggConfigs,
|
||||
SearchSourceFields,
|
||||
TimefilterContract,
|
||||
AggConfigSerialized,
|
||||
} from '../../../plugins/data/public';
|
||||
import { ExpressionAstExpression } from '../../expressions/public';
|
||||
|
||||
|
@ -24,7 +24,7 @@ export interface SavedVisState {
|
|||
title: string;
|
||||
type: string;
|
||||
params: VisParams;
|
||||
aggs: AggConfigOptions[];
|
||||
aggs: AggConfigSerialized[];
|
||||
}
|
||||
|
||||
export interface ISavedVis {
|
||||
|
|
|
@ -26,7 +26,7 @@ import {
|
|||
IAggConfigs,
|
||||
IndexPattern,
|
||||
ISearchSource,
|
||||
AggConfigOptions,
|
||||
AggConfigSerialized,
|
||||
SearchSourceFields,
|
||||
} from '../../../plugins/data/public';
|
||||
import { BaseVisType } from './vis_types';
|
||||
|
@ -34,7 +34,7 @@ import { VisParams } from '../common/types';
|
|||
|
||||
export interface SerializedVisData {
|
||||
expression?: string;
|
||||
aggs: AggConfigOptions[];
|
||||
aggs: AggConfigSerialized[];
|
||||
searchSource: SearchSourceFields;
|
||||
savedSearchId?: string;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ export class Vis<TVisParams = VisParams> {
|
|||
}
|
||||
}
|
||||
|
||||
private initializeDefaultsFromSchemas(configStates: AggConfigOptions[], schemas: any) {
|
||||
private initializeDefaultsFromSchemas(configStates: AggConfigSerialized[], schemas: any) {
|
||||
// Set the defaults for any schema which has them. If the defaults
|
||||
// for some reason has more then the max only set the max number
|
||||
// of defaults (not sure why a someone define more...
|
||||
|
|
|
@ -8,3 +8,16 @@
|
|||
|
||||
export const STATE_STORAGE_KEY = '_a';
|
||||
export const GLOBAL_STATE_STORAGE_KEY = '_g';
|
||||
|
||||
export const APP_NAME = 'visualize';
|
||||
|
||||
export const VisualizeConstants = {
|
||||
VISUALIZE_BASE_PATH: '/app/visualize',
|
||||
LANDING_PAGE_PATH: '/',
|
||||
WIZARD_STEP_1_PAGE_PATH: '/new',
|
||||
WIZARD_STEP_2_PAGE_PATH: '/new/configure',
|
||||
CREATE_PATH: '/create',
|
||||
EDIT_PATH: '/edit',
|
||||
EDIT_BY_VALUE_PATH: '/edit_by_value',
|
||||
APP_ID: 'visualize',
|
||||
};
|
||||
|
|
133
src/plugins/visualize/common/locator.test.ts
Normal file
133
src/plugins/visualize/common/locator.test.ts
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { VisualizeLocatorDefinition } from './locator';
|
||||
import { FilterStateStore } from '../../data/common';
|
||||
|
||||
describe('visualize locator', () => {
|
||||
let definition: VisualizeLocatorDefinition;
|
||||
|
||||
beforeEach(() => {
|
||||
definition = new VisualizeLocatorDefinition();
|
||||
});
|
||||
|
||||
it('returns a location for "create" path', async () => {
|
||||
const location = await definition.getLocation({});
|
||||
|
||||
expect(location.app).toMatchInlineSnapshot(`"visualize"`);
|
||||
expect(location.path).toMatchInlineSnapshot(`"#/create?_g=()&_a=()"`);
|
||||
expect(location.state).toMatchInlineSnapshot(`Object {}`);
|
||||
});
|
||||
|
||||
it('returns a location for "edit" path', async () => {
|
||||
const location = await definition.getLocation({
|
||||
visId: 'test',
|
||||
vis: {
|
||||
title: 'test',
|
||||
type: 'test',
|
||||
aggs: [],
|
||||
params: {},
|
||||
},
|
||||
});
|
||||
|
||||
expect(location.app).toMatchInlineSnapshot(`"visualize"`);
|
||||
expect(location.path).toMatchInlineSnapshot(
|
||||
`"#/edit/test?_g=()&_a=(vis:(aggs:!(),params:(),title:test,type:test))&type=test"`
|
||||
);
|
||||
expect(location.state).toMatchInlineSnapshot(`Object {}`);
|
||||
});
|
||||
|
||||
it('creates a location with query, filters (global and app), refresh interval and time range', async () => {
|
||||
const location = await definition.getLocation({
|
||||
visId: '123',
|
||||
vis: {
|
||||
title: 'test',
|
||||
type: 'test',
|
||||
aggs: [],
|
||||
params: {},
|
||||
},
|
||||
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
|
||||
refreshInterval: { pause: false, value: 300 },
|
||||
filters: [
|
||||
{
|
||||
meta: {
|
||||
alias: null,
|
||||
disabled: false,
|
||||
negate: false,
|
||||
},
|
||||
query: { query: 'hi' },
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
alias: null,
|
||||
disabled: false,
|
||||
negate: false,
|
||||
},
|
||||
query: { query: 'hi' },
|
||||
$state: {
|
||||
store: FilterStateStore.GLOBAL_STATE,
|
||||
},
|
||||
},
|
||||
],
|
||||
query: { query: 'bye', language: 'kuery' },
|
||||
});
|
||||
|
||||
expect(location.app).toMatchInlineSnapshot(`"visualize"`);
|
||||
|
||||
expect(location.path.match(/filters:/g)?.length).toBe(2);
|
||||
expect(location.path.match(/refreshInterval:/g)?.length).toBe(1);
|
||||
expect(location.path.match(/time:/g)?.length).toBe(1);
|
||||
expect(location.path).toMatchInlineSnapshot(
|
||||
`"#/edit/123?_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,negate:!f),query:(query:hi))),refreshInterval:(pause:!f,value:300),time:(from:now-15m,mode:relative,to:now))&_a=(filters:!((meta:(alias:!n,disabled:!f,negate:!f),query:(query:hi))),query:(language:kuery,query:bye),vis:(aggs:!(),params:(),title:test,type:test))&type=test"`
|
||||
);
|
||||
|
||||
expect(location.state).toMatchInlineSnapshot(`Object {}`);
|
||||
});
|
||||
|
||||
it('creates a location with all values provided', async () => {
|
||||
const indexPattern = 'indexPatternTest';
|
||||
const savedSearchId = 'savedSearchIdTest';
|
||||
const location = await definition.getLocation({
|
||||
visId: '123',
|
||||
vis: {
|
||||
title: 'test',
|
||||
type: 'test',
|
||||
aggs: [],
|
||||
params: {},
|
||||
},
|
||||
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
|
||||
refreshInterval: { pause: false, value: 300 },
|
||||
filters: [
|
||||
{
|
||||
meta: {
|
||||
alias: null,
|
||||
disabled: false,
|
||||
negate: false,
|
||||
},
|
||||
query: { query: 'hi' },
|
||||
},
|
||||
],
|
||||
query: { query: 'bye', language: 'kuery' },
|
||||
linked: true,
|
||||
uiState: {
|
||||
fakeUIState: 'fakeUIState',
|
||||
this: 'value contains a spaces that should be encoded',
|
||||
},
|
||||
indexPattern,
|
||||
savedSearchId,
|
||||
});
|
||||
|
||||
expect(location.app).toMatchInlineSnapshot(`"visualize"`);
|
||||
expect(location.path).toContain(indexPattern);
|
||||
expect(location.path).toContain(savedSearchId);
|
||||
expect(location.path).toMatchInlineSnapshot(
|
||||
`"#/edit/123?_g=(filters:!(),refreshInterval:(pause:!f,value:300),time:(from:now-15m,mode:relative,to:now))&_a=(filters:!((meta:(alias:!n,disabled:!f,negate:!f),query:(query:hi))),linked:!t,query:(language:kuery,query:bye),uiState:(fakeUIState:fakeUIState,this:'value%20contains%20a%20spaces%20that%20should%20be%20encoded'),vis:(aggs:!(),params:(),title:test,type:test))&indexPattern=indexPatternTest&savedSearchId=savedSearchIdTest&type=test"`
|
||||
);
|
||||
expect(location.state).toMatchInlineSnapshot(`Object {}`);
|
||||
});
|
||||
});
|
133
src/plugins/visualize/common/locator.ts
Normal file
133
src/plugins/visualize/common/locator.ts
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { SerializableRecord, Serializable } from '@kbn/utility-types';
|
||||
import { omitBy } from 'lodash';
|
||||
import type { ParsedQuery } from 'query-string';
|
||||
import { stringify } from 'query-string';
|
||||
import rison from 'rison-node';
|
||||
import type { Filter, Query, RefreshInterval, TimeRange } from 'src/plugins/data/common';
|
||||
import type { LocatorDefinition, LocatorPublic } from 'src/plugins/share/common';
|
||||
import { isFilterPinned } from '../../data/common';
|
||||
import { url } from '../../kibana_utils/common';
|
||||
import { GLOBAL_STATE_STORAGE_KEY, STATE_STORAGE_KEY, VisualizeConstants } from './constants';
|
||||
import { PureVisState } from './types';
|
||||
|
||||
const removeEmptyKeys = (o: Record<string, Serializable>): Record<string, Serializable> =>
|
||||
omitBy(o, (v) => v == null);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
export type VisualizeLocatorParams = {
|
||||
/**
|
||||
* The ID of the saved visualization to load.
|
||||
*/
|
||||
visId?: string;
|
||||
|
||||
/**
|
||||
* Global- and app-level filters to apply to data loaded by visualize.
|
||||
*/
|
||||
filters?: Filter[];
|
||||
|
||||
/**
|
||||
* Time range to apply to data loaded by visualize.
|
||||
*/
|
||||
timeRange?: TimeRange;
|
||||
|
||||
/**
|
||||
* How frequently to poll for data.
|
||||
*/
|
||||
refreshInterval?: RefreshInterval;
|
||||
|
||||
/**
|
||||
* The query to use in to load data in visualize.
|
||||
*/
|
||||
query?: Query;
|
||||
|
||||
/**
|
||||
* UI state to be passed on to the current visualization. This value is opaque from the perspective of visualize.
|
||||
*/
|
||||
uiState?: SerializableRecord;
|
||||
|
||||
/**
|
||||
* Serialized visualization.
|
||||
*
|
||||
* @note This is required to navigate to "create" page (i.e., when no `visId` has been provided).
|
||||
*/
|
||||
vis?: PureVisState;
|
||||
|
||||
/**
|
||||
* Whether this visualization is linked a saved search.
|
||||
*/
|
||||
linked?: boolean;
|
||||
|
||||
/**
|
||||
* The saved search used as the source of the visualization.
|
||||
*/
|
||||
savedSearchId?: string;
|
||||
|
||||
/**
|
||||
* The saved search used as the source of the visualization.
|
||||
*/
|
||||
indexPattern?: string;
|
||||
};
|
||||
|
||||
export type VisualizeAppLocator = LocatorPublic<VisualizeLocatorParams>;
|
||||
|
||||
export const VISUALIZE_APP_LOCATOR = 'VISUALIZE_APP_LOCATOR';
|
||||
|
||||
export class VisualizeLocatorDefinition implements LocatorDefinition<VisualizeLocatorParams> {
|
||||
id = VISUALIZE_APP_LOCATOR;
|
||||
|
||||
public async getLocation({
|
||||
visId,
|
||||
timeRange,
|
||||
filters,
|
||||
refreshInterval,
|
||||
linked,
|
||||
uiState,
|
||||
query,
|
||||
vis,
|
||||
savedSearchId,
|
||||
indexPattern,
|
||||
}: VisualizeLocatorParams) {
|
||||
let path = visId
|
||||
? `#${VisualizeConstants.EDIT_PATH}/${visId}`
|
||||
: `#${VisualizeConstants.CREATE_PATH}`;
|
||||
|
||||
const urlState: ParsedQuery = {
|
||||
[GLOBAL_STATE_STORAGE_KEY]: rison.encode(
|
||||
removeEmptyKeys({
|
||||
time: timeRange,
|
||||
filters: filters?.filter((f) => isFilterPinned(f)),
|
||||
refreshInterval,
|
||||
})
|
||||
),
|
||||
[STATE_STORAGE_KEY]: rison.encode(
|
||||
removeEmptyKeys({
|
||||
linked,
|
||||
filters: filters?.filter((f) => !isFilterPinned(f)),
|
||||
uiState,
|
||||
query,
|
||||
vis,
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
path += `?${stringify(url.encodeQuery(urlState), { encode: false, sort: false })}`;
|
||||
|
||||
const otherParams = stringify({ type: vis?.type, savedSearchId, indexPattern });
|
||||
|
||||
if (otherParams) path += `&${otherParams}`;
|
||||
|
||||
return {
|
||||
app: VisualizeConstants.APP_ID,
|
||||
path,
|
||||
state: {},
|
||||
};
|
||||
}
|
||||
}
|
10
src/plugins/visualize/common/types.ts
Normal file
10
src/plugins/visualize/common/types.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import type { SavedVisState } from 'src/plugins/visualizations/common/types';
|
||||
|
||||
export type PureVisState = SavedVisState;
|
|
@ -9,6 +9,8 @@
|
|||
import type { EventEmitter } from 'events';
|
||||
import type { History } from 'history';
|
||||
|
||||
import type { SerializableRecord } from '@kbn/utility-types';
|
||||
|
||||
import type {
|
||||
CoreStart,
|
||||
PluginInitializerContext,
|
||||
|
@ -19,7 +21,6 @@ import type {
|
|||
} from 'kibana/public';
|
||||
|
||||
import type {
|
||||
SavedVisState,
|
||||
VisualizationsStart,
|
||||
Vis,
|
||||
VisualizeEmbeddableContract,
|
||||
|
@ -45,11 +46,11 @@ import type { DashboardStart } from '../../../dashboard/public';
|
|||
import type { SavedObjectsTaggingApi } from '../../../saved_objects_tagging_oss/public';
|
||||
import type { UsageCollectionStart } from '../../../usage_collection/public';
|
||||
|
||||
export type PureVisState = SavedVisState;
|
||||
import { PureVisState } from '../../common/types';
|
||||
|
||||
export interface VisualizeAppState {
|
||||
filters: Filter[];
|
||||
uiState: Record<string, unknown>;
|
||||
uiState: SerializableRecord;
|
||||
vis: PureVisState;
|
||||
query: Query;
|
||||
savedQuery?: string;
|
||||
|
@ -103,6 +104,7 @@ export interface VisualizeServices extends CoreStart {
|
|||
savedObjectsTagging?: SavedObjectsTaggingApi;
|
||||
presentationUtil: PresentationUtilPluginStart;
|
||||
usageCollection?: UsageCollectionStart;
|
||||
getKibanaVersion: () => string;
|
||||
}
|
||||
|
||||
export interface SavedVisInstance {
|
||||
|
@ -146,3 +148,5 @@ export interface EditorRenderProps {
|
|||
*/
|
||||
linked: boolean;
|
||||
}
|
||||
|
||||
export { PureVisState };
|
||||
|
|
|
@ -63,7 +63,6 @@ const pureTransitions = {
|
|||
function createVisualizeByValueAppState(stateDefaults: VisualizeAppState) {
|
||||
const initialState = migrateAppState({
|
||||
...stateDefaults,
|
||||
...stateDefaults,
|
||||
});
|
||||
const stateContainer = createStateContainer<VisualizeAppState, VisualizeAppStateTransitions>(
|
||||
initialState,
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { parse } from 'query-string';
|
||||
|
||||
import { Capabilities } from 'src/core/public';
|
||||
import { TopNavMenuData } from 'src/plugins/navigation/public';
|
||||
|
@ -33,6 +35,7 @@ import {
|
|||
import { APP_NAME, VisualizeConstants } from '../visualize_constants';
|
||||
import { getEditBreadcrumbs } from './breadcrumbs';
|
||||
import { EmbeddableStateTransfer } from '../../../../embeddable/public';
|
||||
import { VISUALIZE_APP_LOCATOR, VisualizeLocatorParams } from '../../../common/locator';
|
||||
|
||||
interface VisualizeCapabilities {
|
||||
createShortUrl: boolean;
|
||||
|
@ -95,6 +98,7 @@ export const getTopNavConfig = (
|
|||
savedObjectsTagging,
|
||||
presentationUtil,
|
||||
usageCollection,
|
||||
getKibanaVersion,
|
||||
}: VisualizeServices
|
||||
) => {
|
||||
const { vis, embeddableHandler } = visInstance;
|
||||
|
@ -279,6 +283,22 @@ export const getTopNavConfig = (
|
|||
testId: 'shareTopNavButton',
|
||||
run: (anchorElement) => {
|
||||
if (share && !embeddableId) {
|
||||
const currentState = stateContainer.getState();
|
||||
const searchParams = parse(history.location.search);
|
||||
const params: VisualizeLocatorParams = {
|
||||
visId: savedVis?.id,
|
||||
filters: currentState.filters,
|
||||
refreshInterval: undefined,
|
||||
timeRange: data.query.timefilter.timefilter.getTime(),
|
||||
uiState: currentState.uiState,
|
||||
query: currentState.query,
|
||||
vis: currentState.vis,
|
||||
linked: currentState.linked,
|
||||
indexPattern:
|
||||
visInstance.savedSearch?.searchSource?.getField('index')?.id ??
|
||||
(searchParams.indexPattern as string),
|
||||
savedSearchId: visInstance.savedSearch?.id ?? (searchParams.savedSearchId as string),
|
||||
};
|
||||
// TODO: support sharing in by-value mode
|
||||
share.toggleShareContextMenu({
|
||||
anchorElement,
|
||||
|
@ -288,7 +308,17 @@ export const getTopNavConfig = (
|
|||
objectId: savedVis?.id,
|
||||
objectType: 'visualization',
|
||||
sharingData: {
|
||||
title: savedVis?.title,
|
||||
title:
|
||||
savedVis?.title ||
|
||||
i18n.translate('visualize.reporting.defaultReportTitle', {
|
||||
defaultMessage: 'Visualization [{date}]',
|
||||
values: { date: moment().toISOString(true) },
|
||||
}),
|
||||
locatorParams: {
|
||||
id: VISUALIZE_APP_LOCATOR,
|
||||
version: getKibanaVersion(),
|
||||
params,
|
||||
},
|
||||
},
|
||||
isDirty: hasUnappliedChanges || hasUnsavedChanges,
|
||||
showPublicUrlSwitch,
|
||||
|
|
|
@ -27,7 +27,6 @@ export const visualizeAppStateStub: VisualizeAppState = {
|
|||
{
|
||||
id: '1',
|
||||
enabled: true,
|
||||
// @ts-expect-error
|
||||
type: 'avg',
|
||||
schema: 'metric',
|
||||
params: { field: 'total_quantity', customLabel: 'average items' },
|
||||
|
|
|
@ -157,7 +157,6 @@ describe('useVisualizeAppState', () => {
|
|||
};
|
||||
|
||||
it('should successfully update vis state and set up app state container', async () => {
|
||||
// @ts-expect-error
|
||||
stateContainerGetStateMock.mockImplementation(() => state);
|
||||
const { result, waitForNextUpdate } = renderHook(() =>
|
||||
useVisualizeAppState(mockServices, eventEmitter, savedVisInstance)
|
||||
|
@ -204,7 +203,6 @@ describe('useVisualizeAppState', () => {
|
|||
|
||||
it(`should add warning toast and redirect to the landing page
|
||||
if setting new vis state was not successful, e.x. invalid query params`, async () => {
|
||||
// @ts-expect-error
|
||||
stateContainerGetStateMock.mockImplementation(() => state);
|
||||
// @ts-expect-error
|
||||
savedVisInstance.vis.setState.mockRejectedValue({
|
||||
|
|
|
@ -6,15 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export const APP_NAME = 'visualize';
|
||||
|
||||
export const VisualizeConstants = {
|
||||
VISUALIZE_BASE_PATH: '/app/visualize',
|
||||
LANDING_PAGE_PATH: '/',
|
||||
WIZARD_STEP_1_PAGE_PATH: '/new',
|
||||
WIZARD_STEP_2_PAGE_PATH: '/new/configure',
|
||||
CREATE_PATH: '/create',
|
||||
EDIT_PATH: '/edit',
|
||||
EDIT_BY_VALUE_PATH: '/edit_by_value',
|
||||
APP_ID: 'visualize',
|
||||
};
|
||||
export { VisualizeConstants, APP_NAME } from '../../common/constants';
|
||||
|
|
|
@ -47,6 +47,7 @@ import type { UsageCollectionStart } from '../../usage_collection/public';
|
|||
|
||||
import { setVisEditorsRegistry, setUISettings, setUsageCollector } from './services';
|
||||
import { createVisEditorsRegistry, VisEditorsRegistry } from './vis_editors_registry';
|
||||
import { VisualizeLocatorDefinition } from '../common/locator';
|
||||
|
||||
export interface VisualizePluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
|
@ -92,7 +93,7 @@ export class VisualizePlugin
|
|||
|
||||
public setup(
|
||||
core: CoreSetup<VisualizePluginStartDependencies>,
|
||||
{ home, urlForwarding, data }: VisualizePluginSetupDependencies
|
||||
{ home, urlForwarding, data, share }: VisualizePluginSetupDependencies
|
||||
) {
|
||||
const {
|
||||
appMounted,
|
||||
|
@ -209,6 +210,7 @@ export class VisualizePlugin
|
|||
savedObjectsTagging: pluginsStart.savedObjectsTaggingOss?.getTaggingApi(),
|
||||
presentationUtil: pluginsStart.presentationUtil,
|
||||
usageCollection: pluginsStart.usageCollection,
|
||||
getKibanaVersion: () => this.initializerContext.env.packageInfo.version,
|
||||
};
|
||||
|
||||
params.element.classList.add('visAppWrapper');
|
||||
|
@ -241,6 +243,10 @@ export class VisualizePlugin
|
|||
});
|
||||
}
|
||||
|
||||
if (share) {
|
||||
share.url.locators.create(new VisualizeLocatorDefinition());
|
||||
}
|
||||
|
||||
return {
|
||||
visEditorsRegistry: this.visEditorsRegistry,
|
||||
} as VisualizePluginSetup;
|
||||
|
|
|
@ -6,11 +6,7 @@
|
|||
"declaration": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"include": [
|
||||
"common/**/*",
|
||||
"public/**/*",
|
||||
"server/**/*"
|
||||
],
|
||||
"include": ["common/**/*", "public/**/*", "server/**/*", "../../../typings/**/*"],
|
||||
"references": [
|
||||
{ "path": "../../core/tsconfig.json" },
|
||||
{ "path": "../data/tsconfig.json" },
|
||||
|
@ -28,6 +24,6 @@
|
|||
{ "path": "../kibana_react/tsconfig.json" },
|
||||
{ "path": "../home/tsconfig.json" },
|
||||
{ "path": "../presentation_util/tsconfig.json" },
|
||||
{ "path": "../discover/tsconfig.json" },
|
||||
{ "path": "../discover/tsconfig.json" }
|
||||
]
|
||||
}
|
||||
|
|
|
@ -42,13 +42,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
describe('Print PDF button', () => {
|
||||
it('is not available if new', async () => {
|
||||
it('is available if new', async () => {
|
||||
await PageObjects.common.navigateToUrl('visualize', 'new', { useActualUrl: true });
|
||||
await PageObjects.visualize.clickAggBasedVisualizations();
|
||||
await PageObjects.visualize.clickAreaChart();
|
||||
await PageObjects.visualize.clickNewSearch('ecommerce');
|
||||
await PageObjects.reporting.openPdfReportingPanel();
|
||||
expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be('true');
|
||||
expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null);
|
||||
});
|
||||
|
||||
it('becomes available when saved', async () => {
|
||||
|
|
Loading…
Reference in a new issue