+
-
- {noDataMessage}
-
+
+ {status === PIVOT_PREVIEW_STATUS.LOADING && }
+ {status !== PIVOT_PREVIEW_STATUS.LOADING && (
+
+ )}
+
+ {dataGridColumns.length > 0 && data.length > 0 && (
+
+ )}
);
}
-
- if (columnKeys.length === 0) {
- return null;
- }
-
- return (
-
-
-
- {status === PIVOT_PREVIEW_STATUS.LOADING && }
- {status !== PIVOT_PREVIEW_STATUS.LOADING && (
-
- )}
-
- {dataGridColumns.length > 0 && data.length > 0 && (
-
- )}
-
- );
-});
+);
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx
index 44edd1340e8d6..f45ef7cfddbf9 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.test.tsx
@@ -4,40 +4,44 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { shallow } from 'enzyme';
import React from 'react';
+import { render } from '@testing-library/react';
+import '@testing-library/jest-dom/extend-expect';
-import { KibanaContext } from '../../../../lib/kibana';
-
+import { createPublicShim } from '../../../../../shim';
+import { getAppProviders } from '../../../../app_dependencies';
import {
PivotAggsConfigDict,
PivotGroupByConfigDict,
PIVOT_SUPPORTED_AGGS,
PIVOT_SUPPORTED_GROUP_BY_AGGS,
} from '../../../../common';
-import { StepDefineForm, getAggNameConflictToastMessages } from './step_define_form';
+import { SearchItems } from '../../../../hooks/use_search_items';
-// workaround to make React.memo() work with enzyme
-jest.mock('react', () => {
- const r = jest.requireActual('react');
- return { ...r, memo: (x: any) => x };
-});
+import { StepDefineForm, getAggNameConflictToastMessages } from './step_define_form';
+jest.mock('ui/new_platform');
jest.mock('../../../../../shared_imports');
describe('Transform:
', () => {
test('Minimal initialization', () => {
- // Using a wrapping
element because shallow() would fail
- // with the Provider being the outer most component.
- const wrapper = shallow(
-
-
- {}} />
-
-
+ // Arrange
+ const searchItems = {
+ indexPattern: {
+ title: 'the-index-pattern-title',
+ fields: [] as any[],
+ } as SearchItems['indexPattern'],
+ };
+ const Providers = getAppProviders(createPublicShim());
+ const { getByLabelText } = render(
+
+
+
);
- expect(wrapper).toMatchSnapshot();
+ // Act
+ // Assert
+ expect(getByLabelText('Index pattern')).toBeInTheDocument();
});
});
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx
index 9b96e4b1ee758..f61f54c38680e 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx
@@ -26,6 +26,7 @@ import {
EuiSwitch,
} from '@elastic/eui';
+import { SavedSearchQuery, SearchItems } from '../../../../hooks/use_search_items';
import { useXJsonMode, xJsonMode } from '../../../../hooks/use_x_json_mode';
import { useDocumentationLinks, useToastNotifications } from '../../../../app_dependencies';
import { TransformPivotConfig } from '../../../../common';
@@ -38,12 +39,6 @@ import { PivotPreview } from './pivot_preview';
import { KqlFilterBar } from '../../../../../shared_imports';
import { SwitchModal } from './switch_modal';
-import {
- useKibanaContext,
- InitializedKibanaContextValue,
- SavedSearchQuery,
-} from '../../../../lib/kibana';
-
import {
getPivotQuery,
getPreviewRequestBody,
@@ -78,18 +73,14 @@ export interface StepDefineExposedState {
const defaultSearch = '*';
const emptySearch = '';
-export function getDefaultStepDefineState(
- kibanaContext: InitializedKibanaContextValue
-): StepDefineExposedState {
+export function getDefaultStepDefineState(searchItems: SearchItems): StepDefineExposedState {
return {
aggList: {} as PivotAggsConfigDict,
groupByList: {} as PivotGroupByConfigDict,
isAdvancedPivotEditorEnabled: false,
isAdvancedSourceEditorEnabled: false,
- searchString:
- kibanaContext.currentSavedSearch !== undefined ? kibanaContext.combinedQuery : defaultSearch,
- searchQuery:
- kibanaContext.currentSavedSearch !== undefined ? kibanaContext.combinedQuery : defaultSearch,
+ searchString: searchItems.savedSearch !== undefined ? searchItems.combinedQuery : defaultSearch,
+ searchQuery: searchItems.savedSearch !== undefined ? searchItems.combinedQuery : defaultSearch,
sourceConfigUpdated: false,
valid: false,
};
@@ -242,14 +233,14 @@ export function getAggNameConflictToastMessages(
interface Props {
overrides?: StepDefineExposedState;
onChange(s: StepDefineExposedState): void;
+ searchItems: SearchItems;
}
-export const StepDefineForm: FC
= React.memo(({ overrides = {}, onChange }) => {
- const kibanaContext = useKibanaContext();
+export const StepDefineForm: FC = React.memo(({ overrides = {}, onChange, searchItems }) => {
const toastNotifications = useToastNotifications();
const { esQueryDsl, esTransformPivot } = useDocumentationLinks();
- const defaults = { ...getDefaultStepDefineState(kibanaContext), ...overrides };
+ const defaults = { ...getDefaultStepDefineState(searchItems), ...overrides };
// The search filter
const [searchString, setSearchString] = useState(defaults.searchString);
@@ -267,7 +258,7 @@ export const StepDefineForm: FC = React.memo(({ overrides = {}, onChange
// The list of selected group by fields
const [groupByList, setGroupByList] = useState(defaults.groupByList);
- const indexPattern = kibanaContext.currentIndexPattern;
+ const { indexPattern } = searchItems;
const {
groupByOptions,
@@ -568,7 +559,7 @@ export const StepDefineForm: FC = React.memo(({ overrides = {}, onChange
- {kibanaContext.currentSavedSearch === undefined && typeof searchString === 'string' && (
+ {searchItems.savedSearch === undefined && typeof searchString === 'string' && (
= React.memo(({ overrides = {}, onChange
)}
- {kibanaContext.currentSavedSearch === undefined && (
+ {searchItems.savedSearch === undefined && (
@@ -720,16 +711,15 @@ export const StepDefineForm: FC = React.memo(({ overrides = {}, onChange
)}
- {kibanaContext.currentSavedSearch !== undefined &&
- kibanaContext.currentSavedSearch.id !== undefined && (
-
- {kibanaContext.currentSavedSearch.title}
-
- )}
+ {searchItems.savedSearch !== undefined && searchItems.savedSearch.id !== undefined && (
+
+ {searchItems.savedSearch.title}
+
+ )}
{!isAdvancedPivotEditorEnabled && (
@@ -903,9 +893,14 @@ export const StepDefineForm: FC = React.memo(({ overrides = {}, onChange
-
+
-
+
);
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx
index 78f6fc30f9191..0f7da50bbbade 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.test.tsx
@@ -4,30 +4,35 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { shallow } from 'enzyme';
import React from 'react';
+import { render } from '@testing-library/react';
+import '@testing-library/jest-dom/extend-expect';
-import { KibanaContext } from '../../../../lib/kibana';
-
+import { createPublicShim } from '../../../../../shim';
+import { getAppProviders } from '../../../../app_dependencies';
import {
PivotAggsConfig,
PivotGroupByConfig,
PIVOT_SUPPORTED_AGGS,
PIVOT_SUPPORTED_GROUP_BY_AGGS,
} from '../../../../common';
+import { SearchItems } from '../../../../hooks/use_search_items';
+
import { StepDefineExposedState } from './step_define_form';
import { StepDefineSummary } from './step_define_summary';
-// workaround to make React.memo() work with enzyme
-jest.mock('react', () => {
- const r = jest.requireActual('react');
- return { ...r, memo: (x: any) => x };
-});
-
+jest.mock('ui/new_platform');
jest.mock('../../../../../shared_imports');
describe('Transform: ', () => {
test('Minimal initialization', () => {
+ // Arrange
+ const searchItems = {
+ indexPattern: {
+ title: 'the-index-pattern-title',
+ fields: [] as any[],
+ } as SearchItems['indexPattern'],
+ };
const groupBy: PivotGroupByConfig = {
agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS,
field: 'the-group-by-field',
@@ -40,7 +45,7 @@ describe('Transform: ', () => {
aggName: 'the-group-by-agg-name',
dropDownName: 'the-group-by-drop-down-name',
};
- const props: StepDefineExposedState = {
+ const formState: StepDefineExposedState = {
aggList: { 'the-agg-name': agg },
groupByList: { 'the-group-by-name': groupBy },
isAdvancedPivotEditorEnabled: false,
@@ -51,16 +56,16 @@ describe('Transform: ', () => {
valid: true,
};
- // Using a wrapping element because shallow() would fail
- // with the Provider being the outer most component.
- const wrapper = shallow(
-
-
-
-
-
+ const Providers = getAppProviders(createPublicShim());
+ const { getByText } = render(
+
+
+
);
- expect(wrapper).toMatchSnapshot();
+ // Act
+ // Assert
+ expect(getByText('Group by')).toBeInTheDocument();
+ expect(getByText('Aggregations')).toBeInTheDocument();
});
});
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx
index 30c447f62c760..f8fb9db9bd686 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_summary.tsx
@@ -17,26 +17,27 @@ import {
EuiText,
} from '@elastic/eui';
-import { useKibanaContext } from '../../../../lib/kibana';
+import { getPivotQuery } from '../../../../common';
+import { SearchItems } from '../../../../hooks/use_search_items';
import { AggListSummary } from '../aggregation_list';
import { GroupByListSummary } from '../group_by_list';
-import { PivotPreview } from './pivot_preview';
-import { getPivotQuery } from '../../../../common';
+import { PivotPreview } from './pivot_preview';
import { StepDefineExposedState } from './step_define_form';
const defaultSearch = '*';
const emptySearch = '';
-export const StepDefineSummary: FC
= ({
- searchString,
- searchQuery,
- groupByList,
- aggList,
-}) => {
- const kibanaContext = useKibanaContext();
+interface Props {
+ formState: StepDefineExposedState;
+ searchItems: SearchItems;
+}
+export const StepDefineSummary: FC = ({
+ formState: { searchString, searchQuery, groupByList, aggList },
+ searchItems,
+}) => {
const pivotQuery = getPivotQuery(searchQuery);
let useCodeBlock = false;
let displaySearch;
@@ -55,8 +56,8 @@ export const StepDefineSummary: FC = ({
- {kibanaContext.currentSavedSearch !== undefined &&
- kibanaContext.currentSavedSearch.id === undefined &&
+ {searchItems.savedSearch !== undefined &&
+ searchItems.savedSearch.id === undefined &&
typeof searchString === 'string' && (
= ({
defaultMessage: 'Index pattern',
})}
>
- {kibanaContext.currentIndexPattern.title}
+ {searchItems.indexPattern.title}
{useCodeBlock === false && displaySearch !== emptySearch && (
= ({
)}
- {kibanaContext.currentSavedSearch !== undefined &&
- kibanaContext.currentSavedSearch.id !== undefined && (
-
- {kibanaContext.currentSavedSearch.title}
-
- )}
+ {searchItems.savedSearch !== undefined && searchItems.savedSearch.id !== undefined && (
+
+ {searchItems.savedSearch.title}
+
+ )}
= ({
-
+
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index 5ae2180bfe779..ea9483af49302 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -11,11 +11,15 @@ import { i18n } from '@kbn/i18n';
import { EuiLink, EuiSwitch, EuiFieldText, EuiForm, EuiFormRow, EuiSelect } from '@elastic/eui';
import { toMountPoint } from '../../../../../../../../../../src/plugins/kibana_react/public';
-import { useKibanaContext } from '../../../../lib/kibana';
import { isValidIndexName } from '../../../../../../common/utils/es_utils';
-import { useDocumentationLinks, useToastNotifications } from '../../../../app_dependencies';
+import {
+ useAppDependencies,
+ useDocumentationLinks,
+ useToastNotifications,
+} from '../../../../app_dependencies';
import { ToastNotificationText } from '../../../../components';
+import { SearchItems } from '../../../../hooks/use_search_items';
import { useApi } from '../../../../hooks/use_api';
import { isTransformIdValid, TransformId, TransformPivotConfig } from '../../../../common';
@@ -67,109 +71,129 @@ export function applyTransformConfigToDetailsState(
interface Props {
overrides?: StepDetailsExposedState;
onChange(s: StepDetailsExposedState): void;
+ searchItems: SearchItems;
}
-export const StepDetailsForm: FC = React.memo(({ overrides = {}, onChange }) => {
- const kibanaContext = useKibanaContext();
- const toastNotifications = useToastNotifications();
- const { esIndicesCreateIndex } = useDocumentationLinks();
+export const StepDetailsForm: FC = React.memo(
+ ({ overrides = {}, onChange, searchItems }) => {
+ const deps = useAppDependencies();
+ const toastNotifications = useToastNotifications();
+ const { esIndicesCreateIndex } = useDocumentationLinks();
- const defaults = { ...getDefaultStepDetailsState(), ...overrides };
+ const defaults = { ...getDefaultStepDetailsState(), ...overrides };
- const [transformId, setTransformId] = useState(defaults.transformId);
- const [transformDescription, setTransformDescription] = useState(
- defaults.transformDescription
- );
- const [destinationIndex, setDestinationIndex] = useState(defaults.destinationIndex);
- const [transformIds, setTransformIds] = useState([]);
- const [indexNames, setIndexNames] = useState([]);
- const [indexPatternTitles, setIndexPatternTitles] = useState([]);
- const [createIndexPattern, setCreateIndexPattern] = useState(defaults.createIndexPattern);
+ const [transformId, setTransformId] = useState(defaults.transformId);
+ const [transformDescription, setTransformDescription] = useState(
+ defaults.transformDescription
+ );
+ const [destinationIndex, setDestinationIndex] = useState(
+ defaults.destinationIndex
+ );
+ const [transformIds, setTransformIds] = useState([]);
+ const [indexNames, setIndexNames] = useState([]);
+ const [indexPatternTitles, setIndexPatternTitles] = useState([]);
+ const [createIndexPattern, setCreateIndexPattern] = useState(defaults.createIndexPattern);
- // Continuous mode state
- const [isContinuousModeEnabled, setContinuousModeEnabled] = useState(
- defaults.isContinuousModeEnabled
- );
+ // Continuous mode state
+ const [isContinuousModeEnabled, setContinuousModeEnabled] = useState(
+ defaults.isContinuousModeEnabled
+ );
- const api = useApi();
+ const api = useApi();
- // fetch existing transform IDs and indices once for form validation
- useEffect(() => {
- // use an IIFE to avoid returning a Promise to useEffect.
- (async function() {
- try {
- setTransformIds(
- (await api.getTransforms()).transforms.map(
- (transform: TransformPivotConfig) => transform.id
- )
- );
- } catch (e) {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformList', {
- defaultMessage: 'An error occurred getting the existing transform IDs:',
- }),
- text: toMountPoint(),
- });
- }
+ // fetch existing transform IDs and indices once for form validation
+ useEffect(() => {
+ // use an IIFE to avoid returning a Promise to useEffect.
+ (async function() {
+ try {
+ setTransformIds(
+ (await api.getTransforms()).transforms.map(
+ (transform: TransformPivotConfig) => transform.id
+ )
+ );
+ } catch (e) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformList', {
+ defaultMessage: 'An error occurred getting the existing transform IDs:',
+ }),
+ text: toMountPoint(),
+ });
+ }
- try {
- setIndexNames((await api.getIndices()).map(index => index.name));
- } catch (e) {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIndexNames', {
- defaultMessage: 'An error occurred getting the existing index names:',
- }),
- text: toMountPoint(),
- });
- }
+ try {
+ setIndexNames((await api.getIndices()).map(index => index.name));
+ } catch (e) {
+ toastNotifications.addDanger({
+ title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIndexNames', {
+ defaultMessage: 'An error occurred getting the existing index names:',
+ }),
+ text: toMountPoint(),
+ });
+ }
- try {
- setIndexPatternTitles(await kibanaContext.indexPatterns.getTitles());
- } catch (e) {
- toastNotifications.addDanger({
- title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIndexPatternTitles', {
- defaultMessage: 'An error occurred getting the existing index pattern titles:',
- }),
- text: toMountPoint(),
- });
- }
- })();
- // custom comparison
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [kibanaContext.initialized]);
+ try {
+ setIndexPatternTitles(await deps.plugins.data.indexPatterns.getTitles());
+ } catch (e) {
+ toastNotifications.addDanger({
+ title: i18n.translate(
+ 'xpack.transform.stepDetailsForm.errorGettingIndexPatternTitles',
+ {
+ defaultMessage: 'An error occurred getting the existing index pattern titles:',
+ }
+ ),
+ text: toMountPoint(),
+ });
+ }
+ })();
+ // run once
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
- const dateFieldNames = kibanaContext.currentIndexPattern.fields
- .filter(f => f.type === 'date')
- .map(f => f.name)
- .sort();
- const isContinuousModeAvailable = dateFieldNames.length > 0;
- const [continuousModeDateField, setContinuousModeDateField] = useState(
- isContinuousModeAvailable ? dateFieldNames[0] : ''
- );
- const [continuousModeDelay, setContinuousModeDelay] = useState(defaults.continuousModeDelay);
- const isContinuousModeDelayValid = delayValidator(continuousModeDelay);
+ const dateFieldNames = searchItems.indexPattern.fields
+ .filter(f => f.type === 'date')
+ .map(f => f.name)
+ .sort();
+ const isContinuousModeAvailable = dateFieldNames.length > 0;
+ const [continuousModeDateField, setContinuousModeDateField] = useState(
+ isContinuousModeAvailable ? dateFieldNames[0] : ''
+ );
+ const [continuousModeDelay, setContinuousModeDelay] = useState(defaults.continuousModeDelay);
+ const isContinuousModeDelayValid = delayValidator(continuousModeDelay);
- const transformIdExists = transformIds.some(id => transformId === id);
- const transformIdEmpty = transformId === '';
- const transformIdValid = isTransformIdValid(transformId);
+ const transformIdExists = transformIds.some(id => transformId === id);
+ const transformIdEmpty = transformId === '';
+ const transformIdValid = isTransformIdValid(transformId);
- const indexNameExists = indexNames.some(name => destinationIndex === name);
- const indexNameEmpty = destinationIndex === '';
- const indexNameValid = isValidIndexName(destinationIndex);
- const indexPatternTitleExists = indexPatternTitles.some(name => destinationIndex === name);
+ const indexNameExists = indexNames.some(name => destinationIndex === name);
+ const indexNameEmpty = destinationIndex === '';
+ const indexNameValid = isValidIndexName(destinationIndex);
+ const indexPatternTitleExists = indexPatternTitles.some(name => destinationIndex === name);
- const valid =
- !transformIdEmpty &&
- transformIdValid &&
- !transformIdExists &&
- !indexNameEmpty &&
- indexNameValid &&
- (!indexPatternTitleExists || !createIndexPattern) &&
- (!isContinuousModeAvailable || (isContinuousModeAvailable && isContinuousModeDelayValid));
+ const valid =
+ !transformIdEmpty &&
+ transformIdValid &&
+ !transformIdExists &&
+ !indexNameEmpty &&
+ indexNameValid &&
+ (!indexPatternTitleExists || !createIndexPattern) &&
+ (!isContinuousModeAvailable || (isContinuousModeAvailable && isContinuousModeDelayValid));
- // expose state to wizard
- useEffect(() => {
- onChange({
+ // expose state to wizard
+ useEffect(() => {
+ onChange({
+ continuousModeDateField,
+ continuousModeDelay,
+ createIndexPattern,
+ isContinuousModeEnabled,
+ transformId,
+ transformDescription,
+ destinationIndex,
+ touched: true,
+ valid,
+ });
+ // custom comparison
+ /* eslint-disable react-hooks/exhaustive-deps */
+ }, [
continuousModeDateField,
continuousModeDelay,
createIndexPattern,
@@ -177,232 +201,223 @@ export const StepDetailsForm: FC = React.memo(({ overrides = {}, onChange
transformId,
transformDescription,
destinationIndex,
- touched: true,
valid,
- });
- // custom comparison
- /* eslint-disable react-hooks/exhaustive-deps */
- }, [
- continuousModeDateField,
- continuousModeDelay,
- createIndexPattern,
- isContinuousModeEnabled,
- transformId,
- transformDescription,
- destinationIndex,
- valid,
- /* eslint-enable react-hooks/exhaustive-deps */
- ]);
+ /* eslint-enable react-hooks/exhaustive-deps */
+ ]);
- return (
-
-
-
- setTransformId(e.target.value)}
- aria-label={i18n.translate(
- 'xpack.transform.stepDetailsForm.transformIdInputAriaLabel',
- {
- defaultMessage: 'Choose a unique transform ID.',
- }
- )}
+ return (
+
+
+
-
-
- setTransformDescription(e.target.value)}
- aria-label={i18n.translate(
- 'xpack.transform.stepDetailsForm.transformDescriptionInputAriaLabel',
- {
- defaultMessage: 'Choose an optional transform description.',
- }
- )}
- data-test-subj="transformDescriptionInput"
- />
-
-
- {i18n.translate('xpack.transform.stepDetailsForm.destinationIndexInvalidError', {
- defaultMessage: 'Invalid destination index name.',
- })}
-
-
- {i18n.translate(
- 'xpack.transform.stepDetailsForm.destinationIndexInvalidErrorLink',
- {
- defaultMessage: 'Learn more about index name limitations.',
- }
- )}
-
- ,
- ]
- }
- >
- setDestinationIndex(e.target.value)}
- aria-label={i18n.translate(
- 'xpack.transform.stepDetailsForm.destinationIndexInputAriaLabel',
+ error={[
+ ...(!transformIdEmpty && !transformIdValid
+ ? [
+ i18n.translate('xpack.transform.stepDetailsForm.transformIdInvalidError', {
+ defaultMessage:
+ 'Must contain lowercase alphanumeric characters (a-z and 0-9), hyphens, and underscores only and must start and end with alphanumeric characters.',
+ }),
+ ]
+ : []),
+ ...(transformIdExists
+ ? [
+ i18n.translate('xpack.transform.stepDetailsForm.transformIdExistsError', {
+ defaultMessage: 'A transform with this ID already exists.',
+ }),
+ ]
+ : []),
+ ]}
+ >
+ setTransformId(e.target.value)}
+ aria-label={i18n.translate(
+ 'xpack.transform.stepDetailsForm.transformIdInputAriaLabel',
+ {
+ defaultMessage: 'Choose a unique transform ID.',
+ }
+ )}
+ isInvalid={(!transformIdEmpty && !transformIdValid) || transformIdExists}
+ data-test-subj="transformIdInput"
+ />
+
+
-
-
- setCreateIndexPattern(!createIndexPattern)}
- data-test-subj="transformCreateIndexPatternSwitch"
- />
-
-
- setContinuousModeEnabled(!isContinuousModeEnabled)}
- disabled={isContinuousModeAvailable === false}
- data-test-subj="transformContinuousModeSwitch"
- />
-
- {isContinuousModeEnabled && (
-
-
+ setTransformDescription(e.target.value)}
+ aria-label={i18n.translate(
+ 'xpack.transform.stepDetailsForm.transformDescriptionInputAriaLabel',
{
- defaultMessage: 'Date field',
+ defaultMessage: 'Choose an optional transform description.',
}
)}
- helpText={i18n.translate(
- 'xpack.transform.stepDetailsForm.continuousModeDateFieldHelpText',
+ data-test-subj="transformDescriptionInput"
+ />
+
+
+ {i18n.translate('xpack.transform.stepDetailsForm.destinationIndexInvalidError', {
+ defaultMessage: 'Invalid destination index name.',
+ })}
+
+
+ {i18n.translate(
+ 'xpack.transform.stepDetailsForm.destinationIndexInvalidErrorLink',
+ {
+ defaultMessage: 'Learn more about index name limitations.',
+ }
+ )}
+
+ ,
+ ]
+ }
+ >
+ setDestinationIndex(e.target.value)}
+ aria-label={i18n.translate(
+ 'xpack.transform.stepDetailsForm.destinationIndexInputAriaLabel',
{
- defaultMessage:
- 'Select the date field that can be used to identify new documents.',
+ defaultMessage: 'Choose a unique destination index name.',
}
)}
- >
- ({ text }))}
- value={continuousModeDateField}
- onChange={e => setContinuousModeDateField(e.target.value)}
- data-test-subj="transformContinuousDateFieldSelect"
- />
-
-
+
+
+
- setContinuousModeDelay(e.target.value)}
- aria-label={i18n.translate(
- 'xpack.transform.stepDetailsForm.continuousModeAriaLabel',
+ checked={createIndexPattern === true}
+ onChange={() => setCreateIndexPattern(!createIndexPattern)}
+ data-test-subj="transformCreateIndexPatternSwitch"
+ />
+
+
+ setContinuousModeEnabled(!isContinuousModeEnabled)}
+ disabled={isContinuousModeAvailable === false}
+ data-test-subj="transformContinuousModeSwitch"
+ />
+
+ {isContinuousModeEnabled && (
+
+
+ ({ text }))}
+ value={continuousModeDateField}
+ onChange={e => setContinuousModeDateField(e.target.value)}
+ data-test-subj="transformContinuousDateFieldSelect"
+ />
+
+
-
-
- )}
-
-
- );
-});
+ error={
+ !isContinuousModeDelayValid && [
+ i18n.translate('xpack.transform.stepDetailsForm.continuousModeDelayError', {
+ defaultMessage: 'Invalid delay format',
+ }),
+ ]
+ }
+ helpText={i18n.translate(
+ 'xpack.transform.stepDetailsForm.continuousModeDelayHelpText',
+ {
+ defaultMessage: 'Time delay between current time and latest input data time.',
+ }
+ )}
+ >
+ setContinuousModeDelay(e.target.value)}
+ aria-label={i18n.translate(
+ 'xpack.transform.stepDetailsForm.continuousModeAriaLabel',
+ {
+ defaultMessage: 'Choose a delay.',
+ }
+ )}
+ isInvalid={!isContinuousModeDelayValid}
+ data-test-subj="transformContinuousDelayInput"
+ />
+
+
+ )}
+
+
+ );
+ }
+);
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx
index f1861755d9742..0773ecbb1d8d3 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx
@@ -10,9 +10,8 @@ import { i18n } from '@kbn/i18n';
import { EuiSteps, EuiStepStatus } from '@elastic/eui';
-import { useKibanaContext } from '../../../../lib/kibana';
-
import { getCreateRequestBody, TransformPivotConfig } from '../../../../common';
+import { SearchItems } from '../../../../hooks/use_search_items';
import {
applyTransformConfigToDefineState,
@@ -46,6 +45,7 @@ interface DefinePivotStepProps {
stepDefineState: StepDefineExposedState;
setCurrentStep: React.Dispatch>;
setStepDefineState: React.Dispatch>;
+ searchItems: SearchItems;
}
const StepDefine: FC = ({
@@ -53,6 +53,7 @@ const StepDefine: FC = ({
stepDefineState,
setCurrentStep,
setStepDefineState,
+ searchItems,
}) => {
const definePivotRef = useRef(null);
@@ -61,31 +62,36 @@ const StepDefine: FC = ({
{isCurrentStep && (
-
+
setCurrentStep(WIZARD_STEPS.DETAILS)}
nextActive={stepDefineState.valid}
/>
)}
- {!isCurrentStep && }
+ {!isCurrentStep && (
+
+ )}
);
};
interface WizardProps {
cloneConfig?: TransformPivotConfig;
+ searchItems: SearchItems;
}
-export const Wizard: FC = React.memo(({ cloneConfig }) => {
- const kibanaContext = useKibanaContext();
-
+export const Wizard: FC = React.memo(({ cloneConfig, searchItems }) => {
// The current WIZARD_STEP
const [currentStep, setCurrentStep] = useState(WIZARD_STEPS.DEFINE);
// The DEFINE state
const [stepDefineState, setStepDefineState] = useState(
- applyTransformConfigToDefineState(getDefaultStepDefineState(kibanaContext), cloneConfig)
+ applyTransformConfigToDefineState(getDefaultStepDefineState(searchItems), cloneConfig)
);
// The DETAILS state
@@ -95,7 +101,11 @@ export const Wizard: FC = React.memo(({ cloneConfig }) => {
const stepDetails =
currentStep === WIZARD_STEPS.DETAILS ? (
-
+
) : (
);
@@ -122,7 +132,7 @@ export const Wizard: FC = React.memo(({ cloneConfig }) => {
}
}, []);
- const indexPattern = kibanaContext.currentIndexPattern;
+ const { indexPattern } = searchItems;
const transformConfig = getCreateRequestBody(
indexPattern.title,
@@ -154,6 +164,7 @@ export const Wizard: FC = React.memo(({ cloneConfig }) => {
stepDefineState={stepDefineState}
setCurrentStep={setCurrentStep}
setStepDefineState={setStepDefineState}
+ searchItems={searchItems}
/>
),
},
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx
index 5196f281adf0a..d09fc0913590e 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx
@@ -22,9 +22,9 @@ import {
import { APP_CREATE_TRANSFORM_CLUSTER_PRIVILEGES } from '../../../../common/constants';
import { useDocumentationLinks } from '../../app_dependencies';
+import { useSearchItems } from '../../hooks/use_search_items';
import { breadcrumbService, docTitleService, BREADCRUMB_SECTION } from '../../services/navigation';
import { PrivilegesWrapper } from '../../lib/authorization';
-import { KibanaProvider, RenderOnlyWithInitializedKibanaContext } from '../../lib/kibana';
import { Wizard } from './components/wizard';
@@ -38,43 +38,41 @@ export const CreateTransformSection: FC = ({ match }) => {
const { esTransform } = useDocumentationLinks();
+ const { searchItems } = useSearchItems(match.params.savedObjectId);
+
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {searchItems !== undefined && }
+
+
);
};
diff --git a/x-pack/legacy/plugins/transform/public/plugin.ts b/x-pack/legacy/plugins/transform/public/plugin.ts
index 23fad00fb0786..7b5fbbb4a2151 100644
--- a/x-pack/legacy/plugins/transform/public/plugin.ts
+++ b/x-pack/legacy/plugins/transform/public/plugin.ts
@@ -11,7 +11,6 @@ import { breadcrumbService } from './app/services/navigation';
import { docTitleService } from './app/services/navigation';
import { textService } from './app/services/text';
import { uiMetricService } from './app/services/ui_metric';
-import { createSavedSearchesLoader } from '../../../../../src/plugins/discover/public';
export class Plugin {
public start(core: ShimCore, plugins: ShimPlugins): void {
@@ -27,7 +26,7 @@ export class Plugin {
savedObjects,
overlays,
} = core;
- const { data, management, savedSearches: coreSavedSearches, uiMetric, xsrfToken } = plugins;
+ const { data, management, uiMetric, xsrfToken } = plugins;
// AppCore/AppPlugins to be passed on as React context
const appDependencies = {
@@ -46,7 +45,6 @@ export class Plugin {
plugins: {
data,
management,
- savedSearches: coreSavedSearches,
xsrfToken,
},
};
@@ -61,14 +59,6 @@ export class Plugin {
}),
order: 3,
mount(params) {
- const savedSearches = createSavedSearchesLoader({
- savedObjectsClient: core.savedObjects.client,
- indexPatterns: plugins.data.indexPatterns,
- chrome: core.chrome,
- overlays: core.overlays,
- });
- coreSavedSearches.setClient(savedSearches);
-
breadcrumbService.setup(params.setBreadcrumbs);
params.setBreadcrumbs([
{
diff --git a/x-pack/legacy/plugins/transform/public/shared_imports.ts b/x-pack/legacy/plugins/transform/public/shared_imports.ts
index b077cd8836c4b..1ca71f8c4aa77 100644
--- a/x-pack/legacy/plugins/transform/public/shared_imports.ts
+++ b/x-pack/legacy/plugins/transform/public/shared_imports.ts
@@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
+export { createSavedSearchesLoader } from '../../../../../src/plugins/discover/public';
export { XJsonMode } from '../../../../plugins/es_ui_shared/console_lang/ace/modes/x_json';
export {
collapseLiteralStrings,
diff --git a/x-pack/legacy/plugins/transform/public/shim.ts b/x-pack/legacy/plugins/transform/public/shim.ts
index 05f7626e25e9d..9941aabcf3255 100644
--- a/x-pack/legacy/plugins/transform/public/shim.ts
+++ b/x-pack/legacy/plugins/transform/public/shim.ts
@@ -13,7 +13,6 @@ import { docTitle } from 'ui/doc_title/doc_title';
import { createUiStatsReporter } from '../../../../../src/legacy/core_plugins/ui_metric/public';
import { TRANSFORM_DOC_PATHS } from './app/constants';
-import { SavedSearchLoader } from '../../../../../src/plugins/discover/public';
export type NpCore = typeof npStart.core;
export type NpPlugins = typeof npStart.plugins;
@@ -33,7 +32,7 @@ export type AppCore = Pick<
| 'overlays'
| 'notifications'
>;
-export type AppPlugins = Pick;
+export type AppPlugins = Pick;
export interface AppDependencies {
core: AppCore;
@@ -61,18 +60,10 @@ export interface ShimPlugins extends NpPlugins {
uiMetric: {
createUiStatsReporter: typeof createUiStatsReporter;
};
- savedSearches: {
- getClient(): any;
- setClient(client: any): void;
- };
xsrfToken: string;
}
export function createPublicShim(): { core: ShimCore; plugins: ShimPlugins } {
- // This is an Angular service, which is why we use this provider pattern
- // to access it within our React app.
- let savedSearches: SavedSearchLoader;
-
const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = npStart.core.docLinks;
return {
@@ -94,12 +85,6 @@ export function createPublicShim(): { core: ShimCore; plugins: ShimPlugins } {
},
plugins: {
...npStart.plugins,
- savedSearches: {
- setClient: (client: any): void => {
- savedSearches = client;
- },
- getClient: (): any => savedSearches,
- },
uiMetric: {
createUiStatsReporter,
},