Skip to content

Commit

Permalink
[ML] Transforms: Adds clone feature to transforms list. (#57837)
Browse files Browse the repository at this point in the history
Adds a Clone action to the transform management list. The action opens the transform wizard with prepopulated configurations based on the selected transform. The fields for the transform name and target index will not be populated to avoid the obvious "already exists" warnings.
  • Loading branch information
walterra authored Feb 21, 2020
1 parent fe932fc commit 96000fa
Show file tree
Hide file tree
Showing 22 changed files with 454 additions and 52 deletions.
5 changes: 5 additions & 0 deletions x-pack/legacy/plugins/transform/public/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { getAppProviders } from './app_dependencies';
import { AuthorizationContext } from './lib/authorization';
import { AppDependencies } from '../shim';

import { CloneTransformSection } from './sections/clone_transform';
import { CreateTransformSection } from './sections/create_transform';
import { TransformManagementSection } from './sections/transform_management';

Expand All @@ -39,6 +40,10 @@ export const App: FC = () => {
return (
<div data-test-subj="transformApp">
<Switch>
<Route
path={`${CLIENT_BASE_PATH}/${SECTION_SLUG.CLONE_TRANSFORM}/:transformId`}
component={CloneTransformSection}
/>
<Route
path={`${CLIENT_BASE_PATH}/${SECTION_SLUG.CREATE_TRANSFORM}/:savedObjectId`}
component={CreateTransformSection}
Expand Down
3 changes: 3 additions & 0 deletions x-pack/legacy/plugins/transform/public/app/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,14 @@ export {
TermsAgg,
} from './pivot_group_by';
export {
defaultQuery,
getPreviewRequestBody,
getCreateRequestBody,
getPivotQuery,
isDefaultQuery,
isMatchAllQuery,
isSimpleQuery,
matchAllQuery,
PivotQuery,
SimpleQuery,
} from './request';
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,26 @@ import { StepDetailsExposedState } from '../sections/create_transform/components
import { PIVOT_SUPPORTED_GROUP_BY_AGGS } from './pivot_group_by';
import { PivotAggsConfig, PIVOT_SUPPORTED_AGGS } from './pivot_aggs';
import {
defaultQuery,
getPreviewRequestBody,
getCreateRequestBody,
getPivotQuery,
isDefaultQuery,
isMatchAllQuery,
isSimpleQuery,
matchAllQuery,
PivotQuery,
} from './request';

const defaultQuery: PivotQuery = { query_string: { query: '*' } };
const matchAllQuery: PivotQuery = { match_all: {} };
const simpleQuery: PivotQuery = { query_string: { query: 'airline:AAL' } };

describe('Transform: Common', () => {
test('isMatchAllQuery()', () => {
expect(isMatchAllQuery(defaultQuery)).toBe(false);
expect(isMatchAllQuery(matchAllQuery)).toBe(true);
expect(isMatchAllQuery(simpleQuery)).toBe(false);
});

test('isSimpleQuery()', () => {
expect(isSimpleQuery(defaultQuery)).toBe(true);
expect(isSimpleQuery(matchAllQuery)).toBe(false);
Expand Down
6 changes: 6 additions & 0 deletions x-pack/legacy/plugins/transform/public/app/common/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ export function isSimpleQuery(arg: any): arg is SimpleQuery {
return arg.query_string !== undefined;
}

export const matchAllQuery = { match_all: {} };
export function isMatchAllQuery(query: any): boolean {
return query.match_all !== undefined && Object.keys(query.match_all).length === 0;
}

export const defaultQuery: PivotQuery = { query_string: { query: '*' } };
export function isDefaultQuery(query: PivotQuery): boolean {
return isSimpleQuery(query) && query.query_string.query === '*';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const CLIENT_BASE_PATH = '/management/elasticsearch/transform';

export enum SECTION_SLUG {
HOME = 'transform_management',
CLONE_TRANSFORM = 'clone_transform',
CREATE_TRANSFORM = 'create_transform',
}

Expand Down
34 changes: 24 additions & 10 deletions x-pack/legacy/plugins/transform/public/app/lib/kibana/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { SavedObjectsClientContract, IUiSettingsClient } from 'src/core/public';
import { SavedObjectsClientContract, SimpleSavedObject, IUiSettingsClient } from 'src/core/public';
import {
IndexPattern,
esQuery,
IndexPatternsContract,
} from '../../../../../../../../src/plugins/data/public';

import { matchAllQuery } from '../../common';

type IndexPatternId = string;
type SavedSearchId = string;

let indexPatternCache = [];
let indexPatternCache: Array<SimpleSavedObject<Record<string, any>>> = [];
let fullIndexPatterns;
let currentIndexPattern = null;
let currentSavedSearch = null;
Expand Down Expand Up @@ -53,6 +55,10 @@ export function loadIndexPatterns(
});
}

export function getIndexPatternIdByTitle(indexPatternTitle: string): string | undefined {
return indexPatternCache.find(d => d?.attributes?.title === indexPatternTitle)?.id;
}

type CombinedQuery = Record<'bool', any> | unknown;

export function loadCurrentIndexPattern(
Expand All @@ -69,12 +75,20 @@ export function loadCurrentSavedSearch(savedSearches: any, savedSearchId: SavedS
return currentSavedSearch;
}

function isIndexPattern(arg: any): arg is IndexPattern {
return arg !== undefined;
}
// Helper for creating the items used for searching and job creation.
export function createSearchItems(
indexPattern: IndexPattern | undefined,
savedSearch: any,
config: IUiSettingsClient
) {
): {
indexPattern: IndexPattern;
savedSearch: any;
query: any;
combinedQuery: CombinedQuery;
} {
// query is only used by the data visualizer as it needs
// a lucene query_string.
// Using a blank query will cause match_all:{} to be used
Expand All @@ -86,17 +100,13 @@ export function createSearchItems(

let combinedQuery: CombinedQuery = {
bool: {
must: [
{
match_all: {},
},
],
must: [matchAllQuery],
},
};

if (indexPattern === undefined && savedSearch !== null && savedSearch.id !== undefined) {
if (!isIndexPattern(indexPattern) && savedSearch !== null && savedSearch.id !== undefined) {
const searchSource = savedSearch.searchSource;
indexPattern = searchSource.getField('index');
indexPattern = searchSource.getField('index') as IndexPattern;

query = searchSource.getField('query');
const fs = searchSource.getField('filter');
Expand All @@ -107,6 +117,10 @@ export function createSearchItems(
combinedQuery = esQuery.buildEsQuery(indexPattern, [query], filters, esQueryConfigs);
}

if (!isIndexPattern(indexPattern)) {
throw new Error('Index Pattern is not defined.');
}

return {
indexPattern,
savedSearch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

export { getIndexPatternIdByTitle, loadIndexPatterns } from './common';
export {
useKibanaContext,
InitializedKibanaContextValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,26 @@

import React, { createContext, useContext, FC } from 'react';

import { IUiSettingsClient } from 'kibana/public';

import { SavedSearch } from '../../../../../../../../src/legacy/core_plugins/kibana/public/discover/np_ready/types';
import {
IndexPattern,
IndexPatternsContract,
} from '../../../../../../../../src/plugins/data/public';
import { KibanaConfig } from '../../../../../../../../src/legacy/server/kbn_server';

// set() method is missing in original d.ts
interface KibanaConfigTypeFix extends KibanaConfig {
set(key: string, value: any): void;
}

interface UninitializedKibanaContextValue {
initialized: boolean;
initialized: false;
}

export interface InitializedKibanaContextValue {
combinedQuery: any;
currentIndexPattern: IndexPattern;
currentSavedSearch: SavedSearch;
indexPatterns: IndexPatternsContract;
initialized: boolean;
initialized: true;
kbnBaseUrl: string;
kibanaConfig: KibanaConfigTypeFix;
kibanaConfig: IUiSettingsClient;
currentIndexPattern: IndexPattern;
currentSavedSearch?: SavedSearch;
}

export type KibanaContextValue = UninitializedKibanaContextValue | InitializedKibanaContextValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
loadCurrentSavedSearch,
} from './common';

import { KibanaContext, KibanaContextValue } from './kibana_context';
import { InitializedKibanaContextValue, KibanaContext, KibanaContextValue } from './kibana_context';

const indexPatterns = npStart.plugins.data.indexPatterns;
const savedObjectsClient = npStart.core.savedObjects.client;
Expand Down Expand Up @@ -52,20 +52,20 @@ export const KibanaProvider: FC<Props> = ({ savedObjectId, children }) => {

const kibanaConfig = npStart.core.uiSettings;

const { indexPattern, savedSearch, combinedQuery } = createSearchItems(
fetchedIndexPattern,
fetchedSavedSearch,
kibanaConfig
);

const kibanaContext = {
const {
indexPattern: currentIndexPattern,
savedSearch: currentSavedSearch,
combinedQuery,
currentIndexPattern: indexPattern,
currentSavedSearch: savedSearch,
} = createSearchItems(fetchedIndexPattern, fetchedSavedSearch, kibanaConfig);

const kibanaContext: InitializedKibanaContextValue = {
indexPatterns,
initialized: true,
kbnBaseUrl: npStart.core.injectedMetadata.getBasePath(),
kibanaConfig,
combinedQuery,
currentIndexPattern,
currentSavedSearch,
};

setContextValue(kibanaContext);
Expand Down
Loading

0 comments on commit 96000fa

Please sign in to comment.