NP Migration: Rollup plugin (#53503)
* Start shimming rollup plugin * continued shimming rollup ui * Remove unnecessarily return * Register management section * Replace ui/chrome * Replace ui/documentation_links * Replace ui/kfetch and ui/courier * Start shimming rollup plugin * continued shimming rollup ui * Remove unnecessarily return * Register management section * Replace ui/chrome * Replace ui/documentation_links * Replace ui/kfetch and ui/courier * Replace ui/notify * Move ui/ imports to legacy_imports.ts * Update NP mock for management * Refactoring * Read body from error object * Update setup_environment.js * Update unit tests * Get rid of injectI18n * Replace npStart and npSetup usage to services * Import search strategy stuff from the top level of the data plugin * Update unit tests * Do not prepend the url * Fix merge conflicts * Refactoring * Revert removal of setUserHasLeftApp * Export getSearchErrorType * Remove extra wrapper - Router * Fix cause prop. * Leave just static imports in legacy_imports.js * Add TS * Pass statusCode instead of statusText * Move template in a separate file * Move app register to setup * Add karma mock for management setup * Add EditorConfigProviderRegistry export Co-authored-by: Maryia Lapata <mary.lopato@gmail.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
326afbc304
commit
0d03ade9ea
|
@ -17,5 +17,5 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { aggTypeFilters } from './agg_type_filters';
|
export { aggTypeFilters, AggTypeFilters } from './agg_type_filters';
|
||||||
export { propFilter } from './prop_filter';
|
export { propFilter } from './prop_filter';
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { aggTypeFieldFilters } from './field_filters';
|
export { aggTypeFieldFilters, AggTypeFieldFilters } from './field_filters';
|
||||||
|
|
|
@ -147,6 +147,13 @@ export const npSetup = {
|
||||||
useChartsTheme: sinon.fake(),
|
useChartsTheme: sinon.fake(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
management: {
|
||||||
|
sections: {
|
||||||
|
getSection: () => ({
|
||||||
|
registerApp: sinon.fake(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,6 +174,11 @@ export const npStart = {
|
||||||
hasItem: sinon.fake(),
|
hasItem: sinon.fake(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
sections: {
|
||||||
|
getSection: () => ({
|
||||||
|
registerApp: sinon.fake(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
embeddable: {
|
embeddable: {
|
||||||
getEmbeddableFactory: sinon.fake(),
|
getEmbeddableFactory: sinon.fake(),
|
||||||
|
|
|
@ -32,7 +32,7 @@ import { DevToolsSetup, DevToolsStart } from '../../../../plugins/dev_tools/publ
|
||||||
import { KibanaLegacySetup, KibanaLegacyStart } from '../../../../plugins/kibana_legacy/public';
|
import { KibanaLegacySetup, KibanaLegacyStart } from '../../../../plugins/kibana_legacy/public';
|
||||||
import { HomePublicPluginSetup, HomePublicPluginStart } from '../../../../plugins/home/public';
|
import { HomePublicPluginSetup, HomePublicPluginStart } from '../../../../plugins/home/public';
|
||||||
import { SharePluginSetup, SharePluginStart } from '../../../../plugins/share/public';
|
import { SharePluginSetup, SharePluginStart } from '../../../../plugins/share/public';
|
||||||
import { ManagementStart } from '../../../../plugins/management/public';
|
import { ManagementSetup, ManagementStart } from '../../../../plugins/management/public';
|
||||||
import { BfetchPublicSetup, BfetchPublicStart } from '../../../../plugins/bfetch/public';
|
import { BfetchPublicSetup, BfetchPublicStart } from '../../../../plugins/bfetch/public';
|
||||||
import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public';
|
import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public';
|
||||||
import {
|
import {
|
||||||
|
@ -54,6 +54,7 @@ export interface PluginsSetup {
|
||||||
kibana_legacy: KibanaLegacySetup;
|
kibana_legacy: KibanaLegacySetup;
|
||||||
share: SharePluginSetup;
|
share: SharePluginSetup;
|
||||||
usageCollection: UsageCollectionSetup;
|
usageCollection: UsageCollectionSetup;
|
||||||
|
management: ManagementSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginsStart {
|
export interface PluginsStart {
|
||||||
|
|
|
@ -17,5 +17,5 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { editorConfigProviders } from './editor_config_providers';
|
export { editorConfigProviders, EditorConfigProviderRegistry } from './editor_config_providers';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
|
|
@ -47,6 +47,8 @@ export {
|
||||||
hasSearchStategyForIndexPattern,
|
hasSearchStategyForIndexPattern,
|
||||||
defaultSearchStrategy,
|
defaultSearchStrategy,
|
||||||
SearchError,
|
SearchError,
|
||||||
|
SearchStrategyProvider,
|
||||||
|
getSearchErrorType,
|
||||||
} from './search_strategy';
|
} from './search_strategy';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import sinon from 'sinon';
|
|
||||||
|
|
||||||
// Register helpers to mock HTTP Requests
|
|
||||||
const registerHttpRequestMockHelpers = server => {
|
|
||||||
const setIndexPatternValidityResponse = response => {
|
|
||||||
const defaultResponse = {
|
|
||||||
doesMatchIndices: true,
|
|
||||||
doesMatchRollupIndices: false,
|
|
||||||
dateFields: ['foo', 'bar'],
|
|
||||||
numericFields: [],
|
|
||||||
keywordFields: [],
|
|
||||||
};
|
|
||||||
server.respondWith(/\/api\/rollup\/index_pattern_validity\/.*/, [
|
|
||||||
200,
|
|
||||||
{ 'Content-Type': 'application/json' },
|
|
||||||
JSON.stringify({ ...defaultResponse, ...response }),
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setCreateJobResponse = (responsePayload = {}) => {
|
|
||||||
server.respondWith(/\/api\/rollup\/create/, [
|
|
||||||
200,
|
|
||||||
{ 'Content-Type': 'application/json' },
|
|
||||||
JSON.stringify(responsePayload),
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setStartJobResponse = () => {
|
|
||||||
server.respondWith(/\/api\/rollup\/start/, [
|
|
||||||
200,
|
|
||||||
{ 'Content-Type': 'application/json' },
|
|
||||||
JSON.stringify({}),
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setLoadJobsResponse = response => {
|
|
||||||
server.respondWith('GET', '/api/rollup/jobs', [
|
|
||||||
200,
|
|
||||||
{ 'Content-Type': 'application/json' },
|
|
||||||
JSON.stringify(response),
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
setIndexPatternValidityResponse,
|
|
||||||
setCreateJobResponse,
|
|
||||||
setLoadJobsResponse,
|
|
||||||
setStartJobResponse,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const init = () => {
|
|
||||||
const server = sinon.fakeServer.create();
|
|
||||||
server.respondImmediately = true;
|
|
||||||
|
|
||||||
// We make requests to APIs which don't impact the UX, e.g. UI metric telemetry,
|
|
||||||
// and we can mock them all with a 200 instead of mocking each one individually.
|
|
||||||
server.respondWith([200, {}, '']);
|
|
||||||
|
|
||||||
return {
|
|
||||||
server,
|
|
||||||
httpRequestsMockHelpers: registerHttpRequestMockHelpers(server),
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -10,7 +10,9 @@ import { setup as jobCloneSetup } from './job_clone.helpers';
|
||||||
|
|
||||||
export { nextTick, getRandomString, findTestSubject } from '../../../../../../test_utils';
|
export { nextTick, getRandomString, findTestSubject } from '../../../../../../test_utils';
|
||||||
|
|
||||||
export { setupEnvironment } from './setup_environment';
|
export { mockHttpRequest } from './setup_environment';
|
||||||
|
|
||||||
|
export { wrapComponent } from './setup_context';
|
||||||
|
|
||||||
export const pageHelpers = {
|
export const pageHelpers = {
|
||||||
jobCreate: { setup: jobCreateSetup },
|
jobCreate: { setup: jobCreateSetup },
|
||||||
|
|
|
@ -10,8 +10,10 @@ import { JobCreate } from '../../../public/crud_app/sections';
|
||||||
import { JOB_TO_CLONE } from './constants';
|
import { JOB_TO_CLONE } from './constants';
|
||||||
import { deserializeJob } from '../../../public/crud_app/services';
|
import { deserializeJob } from '../../../public/crud_app/services';
|
||||||
|
|
||||||
|
import { wrapComponent } from './setup_context';
|
||||||
|
|
||||||
export const setup = props => {
|
export const setup = props => {
|
||||||
const initTestBed = registerTestBed(JobCreate, {
|
const initTestBed = registerTestBed(wrapComponent(JobCreate), {
|
||||||
store: createRollupJobsStore({
|
store: createRollupJobsStore({
|
||||||
cloneJob: { job: deserializeJob(JOB_TO_CLONE.jobs[0]) },
|
cloneJob: { job: deserializeJob(JOB_TO_CLONE.jobs[0]) },
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -10,7 +10,9 @@ import { JobCreate } from '../../../public/crud_app/sections';
|
||||||
|
|
||||||
import { JOB_TO_CREATE } from './constants';
|
import { JOB_TO_CREATE } from './constants';
|
||||||
|
|
||||||
const initTestBed = registerTestBed(JobCreate, { store: rollupJobsStore });
|
import { wrapComponent } from './setup_context';
|
||||||
|
|
||||||
|
const initTestBed = registerTestBed(wrapComponent(JobCreate), { store: rollupJobsStore });
|
||||||
|
|
||||||
export const setup = props => {
|
export const setup = props => {
|
||||||
const testBed = initTestBed(props);
|
const testBed = initTestBed(props);
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { registerRouter } from '../../../public/crud_app/services';
|
||||||
import { createRollupJobsStore } from '../../../public/crud_app/store';
|
import { createRollupJobsStore } from '../../../public/crud_app/store';
|
||||||
import { JobList } from '../../../public/crud_app/sections/job_list';
|
import { JobList } from '../../../public/crud_app/sections/job_list';
|
||||||
|
|
||||||
|
import { wrapComponent } from './setup_context';
|
||||||
|
|
||||||
const testBedConfig = {
|
const testBedConfig = {
|
||||||
store: createRollupJobsStore,
|
store: createRollupJobsStore,
|
||||||
memoryRouter: {
|
memoryRouter: {
|
||||||
|
@ -19,4 +21,4 @@ const testBedConfig = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setup = registerTestBed(JobList, testBedConfig);
|
export const setup = registerTestBed(wrapComponent(JobList), testBedConfig);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { FunctionComponent } from 'react';
|
||||||
|
|
||||||
|
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
import { coreMock } from '../../../../../../../src/core/public/mocks';
|
||||||
|
const startMock = coreMock.createStart();
|
||||||
|
|
||||||
|
const services = {
|
||||||
|
setBreadcrumbs: startMock.chrome.setBreadcrumbs,
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapComponent = (Component: FunctionComponent) => (props: any) => (
|
||||||
|
<KibanaContextProvider services={services}>
|
||||||
|
<Component {...props} />
|
||||||
|
</KibanaContextProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
export { wrapComponent };
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import axios from 'axios';
|
|
||||||
import axiosXhrAdapter from 'axios/lib/adapters/xhr';
|
|
||||||
|
|
||||||
import { setHttp } from '../../../public/crud_app/services';
|
|
||||||
import { init as initHttpRequests } from './http_requests';
|
|
||||||
|
|
||||||
export const setupEnvironment = () => {
|
|
||||||
// axios has a $http like interface so using it to simulate $http
|
|
||||||
setHttp(axios.create({ adapter: axiosXhrAdapter }));
|
|
||||||
|
|
||||||
const { server, httpRequestsMockHelpers } = initHttpRequests();
|
|
||||||
|
|
||||||
return {
|
|
||||||
server,
|
|
||||||
httpRequestsMockHelpers,
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface RequestMocks {
|
||||||
|
jobs?: object;
|
||||||
|
createdJob?: object;
|
||||||
|
indxPatternVldtResp?: object;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockHttpRequest = (
|
||||||
|
http: any,
|
||||||
|
{ jobs = {}, createdJob = {}, indxPatternVldtResp = {} }: RequestMocks = {}
|
||||||
|
) => {
|
||||||
|
http.get.mockImplementation(async (url: string) => {
|
||||||
|
if (url === '/api/rollup/jobs') {
|
||||||
|
return jobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.startsWith('/api/rollup/index_pattern_validity')) {
|
||||||
|
return {
|
||||||
|
doesMatchIndices: true,
|
||||||
|
doesMatchRollupIndices: false,
|
||||||
|
dateFields: ['foo', 'bar'],
|
||||||
|
numericFields: [],
|
||||||
|
keywordFields: [],
|
||||||
|
...indxPatternVldtResp,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
|
// mock '/api/rollup/start'
|
||||||
|
http.post.mockImplementation(async (url: string) => ({}));
|
||||||
|
|
||||||
|
// mock '/api/rollup/create
|
||||||
|
http.put.mockImplementation(async (url: string) => createdJob);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { mockHttpRequest };
|
|
@ -4,7 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setupEnvironment, pageHelpers, nextTick } from './helpers';
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
|
import { mockHttpRequest, pageHelpers, nextTick } from './helpers';
|
||||||
import { JOB_TO_CLONE, JOB_CLONE_INDEX_PATTERN_CHECK } from './helpers/constants';
|
import { JOB_TO_CLONE, JOB_CLONE_INDEX_PATTERN_CHECK } from './helpers/constants';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
@ -17,26 +18,28 @@ const {
|
||||||
} = JOB_TO_CLONE;
|
} = JOB_TO_CLONE;
|
||||||
|
|
||||||
describe('Cloning a rollup job through create job wizard', () => {
|
describe('Cloning a rollup job through create job wizard', () => {
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let server;
|
|
||||||
let find;
|
let find;
|
||||||
let exists;
|
let exists;
|
||||||
let form;
|
let form;
|
||||||
let table;
|
let table;
|
||||||
let actions;
|
let actions;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
|
setHttp(npStart.core.http);
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse(JOB_CLONE_INDEX_PATTERN_CHECK);
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: JOB_CLONE_INDEX_PATTERN_CHECK });
|
||||||
|
|
||||||
({ exists, find, form, actions, table } = setup());
|
({ exists, find, form, actions, table } = setup());
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterEach(() => {
|
||||||
server.restore();
|
npStart.core.http.get.mockClear();
|
||||||
|
npStart.core.http.post.mockClear();
|
||||||
|
npStart.core.http.put.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have fields correctly pre-populated', async () => {
|
it('should have fields correctly pre-populated', async () => {
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
|
|
||||||
import { setupEnvironment, pageHelpers } from './helpers';
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
|
import { mockHttpRequest, pageHelpers } from './helpers';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
|
||||||
|
@ -15,30 +16,31 @@ jest.mock('lodash/function/debounce', () => fn => fn);
|
||||||
const { setup } = pageHelpers.jobCreate;
|
const { setup } = pageHelpers.jobCreate;
|
||||||
|
|
||||||
describe('Create Rollup Job, step 2: Date histogram', () => {
|
describe('Create Rollup Job, step 2: Date histogram', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let find;
|
let find;
|
||||||
let exists;
|
let exists;
|
||||||
let actions;
|
let actions;
|
||||||
let goToStep;
|
let goToStep;
|
||||||
let form;
|
let form;
|
||||||
let getEuiStepsHorizontalActive;
|
let getEuiStepsHorizontalActive;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
|
setHttp(npStart.core.http);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set "default" mock responses by not providing any arguments
|
// Set "default" mock responses by not providing any arguments
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse();
|
mockHttpRequest(npStart.core.http);
|
||||||
|
|
||||||
({ find, exists, actions, form, getEuiStepsHorizontalActive, goToStep } = setup());
|
({ find, exists, actions, form, getEuiStepsHorizontalActive, goToStep } = setup());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
npStart.core.http.post.mockClear();
|
||||||
|
npStart.core.http.put.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
describe('layout', () => {
|
describe('layout', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await goToStep(2);
|
await goToStep(2);
|
||||||
|
@ -71,7 +73,7 @@ describe('Create Rollup Job, step 2: Date histogram', () => {
|
||||||
describe('Date field select', () => {
|
describe('Date field select', () => {
|
||||||
it('should set the options value from the index pattern', async () => {
|
it('should set the options value from the index pattern', async () => {
|
||||||
const dateFields = ['field1', 'field2', 'field3'];
|
const dateFields = ['field1', 'field2', 'field3'];
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ dateFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { dateFields } });
|
||||||
|
|
||||||
await goToStep(2);
|
await goToStep(2);
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ describe('Create Rollup Job, step 2: Date histogram', () => {
|
||||||
|
|
||||||
it('should sort the options in ascending order', async () => {
|
it('should sort the options in ascending order', async () => {
|
||||||
const dateFields = ['field3', 'field2', 'field1'];
|
const dateFields = ['field3', 'field2', 'field1'];
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ dateFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { dateFields } });
|
||||||
|
|
||||||
await goToStep(2);
|
await goToStep(2);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setupEnvironment, pageHelpers } from './helpers';
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
|
import { mockHttpRequest, pageHelpers } from './helpers';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
|
||||||
|
@ -13,8 +14,6 @@ jest.mock('lodash/function/debounce', () => fn => fn);
|
||||||
const { setup } = pageHelpers.jobCreate;
|
const { setup } = pageHelpers.jobCreate;
|
||||||
|
|
||||||
describe('Create Rollup Job, step 4: Histogram', () => {
|
describe('Create Rollup Job, step 4: Histogram', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let find;
|
let find;
|
||||||
let exists;
|
let exists;
|
||||||
let actions;
|
let actions;
|
||||||
|
@ -22,22 +21,26 @@ describe('Create Rollup Job, step 4: Histogram', () => {
|
||||||
let goToStep;
|
let goToStep;
|
||||||
let table;
|
let table;
|
||||||
let form;
|
let form;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
});
|
setHttp(npStart.core.http);
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set "default" mock responses by not providing any arguments
|
// Set "default" mock responses by not providing any arguments
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse();
|
mockHttpRequest(npStart.core.http);
|
||||||
|
|
||||||
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table, form } = setup());
|
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table, form } = setup());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
npStart.core.http.post.mockClear();
|
||||||
|
npStart.core.http.put.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
const numericFields = ['a-numericField', 'b-numericField'];
|
const numericFields = ['a-numericField', 'b-numericField'];
|
||||||
|
|
||||||
const goToStepAndOpenFieldChooser = async () => {
|
const goToStepAndOpenFieldChooser = async () => {
|
||||||
|
@ -108,7 +111,7 @@ describe('Create Rollup Job, step 4: Histogram', () => {
|
||||||
|
|
||||||
describe('when no histogram fields are availalbe', () => {
|
describe('when no histogram fields are availalbe', () => {
|
||||||
it('should indicate it to the user', async () => {
|
it('should indicate it to the user', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields: [] });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields: [] } });
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
|
|
||||||
const { tableCellsValues } = table.getMetaData('rollupJobHistogramFieldChooser-table');
|
const { tableCellsValues } = table.getMetaData('rollupJobHistogramFieldChooser-table');
|
||||||
|
@ -119,7 +122,7 @@ describe('Create Rollup Job, step 4: Histogram', () => {
|
||||||
|
|
||||||
describe('when histogram fields are available', () => {
|
describe('when histogram fields are available', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields } });
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -153,7 +156,7 @@ describe('Create Rollup Job, step 4: Histogram', () => {
|
||||||
|
|
||||||
it('should have a delete button on each row to remove an histogram field', async () => {
|
it('should have a delete button on each row to remove an histogram field', async () => {
|
||||||
// First let's add a term to the list
|
// First let's add a term to the list
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields } });
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
const { rows: fieldChooserRows } = table.getMetaData('rollupJobHistogramFieldChooser-table');
|
const { rows: fieldChooserRows } = table.getMetaData('rollupJobHistogramFieldChooser-table');
|
||||||
fieldChooserRows[0].reactWrapper.simulate('click');
|
fieldChooserRows[0].reactWrapper.simulate('click');
|
||||||
|
@ -180,7 +183,7 @@ describe('Create Rollup Job, step 4: Histogram', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields } });
|
||||||
await goToStep(4);
|
await goToStep(4);
|
||||||
addHistogramFieldToList();
|
addHistogramFieldToList();
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,8 @@ import {
|
||||||
YEAR,
|
YEAR,
|
||||||
} from '../../../../../../src/plugins/es_ui_shared/public/components/cron_editor';
|
} from '../../../../../../src/plugins/es_ui_shared/public/components/cron_editor';
|
||||||
import { indexPatterns } from '../../../../../../src/plugins/data/public';
|
import { indexPatterns } from '../../../../../../src/plugins/data/public';
|
||||||
import { setupEnvironment, pageHelpers } from './helpers';
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
|
import { mockHttpRequest, pageHelpers } from './helpers';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
|
||||||
|
@ -22,29 +23,31 @@ jest.mock('lodash/function/debounce', () => fn => fn);
|
||||||
const { setup } = pageHelpers.jobCreate;
|
const { setup } = pageHelpers.jobCreate;
|
||||||
|
|
||||||
describe('Create Rollup Job, step 1: Logistics', () => {
|
describe('Create Rollup Job, step 1: Logistics', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let find;
|
let find;
|
||||||
let exists;
|
let exists;
|
||||||
let actions;
|
let actions;
|
||||||
let form;
|
let form;
|
||||||
let getEuiStepsHorizontalActive;
|
let getEuiStepsHorizontalActive;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
});
|
setHttp(npStart.core.http);
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set "default" mock responses by not providing any arguments
|
// Set "default" mock responses by not providing any arguments
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse();
|
mockHttpRequest(npStart.core.http);
|
||||||
|
|
||||||
({ find, exists, actions, form, getEuiStepsHorizontalActive } = setup());
|
({ find, exists, actions, form, getEuiStepsHorizontalActive } = setup());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
npStart.core.http.post.mockClear();
|
||||||
|
npStart.core.http.put.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
it('should have the horizontal step active on "Logistics"', () => {
|
it('should have the horizontal step active on "Logistics"', () => {
|
||||||
expect(getEuiStepsHorizontalActive()).toContain('Logistics');
|
expect(getEuiStepsHorizontalActive()).toContain('Logistics');
|
||||||
});
|
});
|
||||||
|
@ -94,14 +97,14 @@ describe('Create Rollup Job, step 1: Logistics', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow an unknown index pattern', async () => {
|
it('should not allow an unknown index pattern', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ doesMatchIndices: false });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { doesMatchIndices: false } });
|
||||||
await form.setInputValue('rollupIndexPattern', 'unknown', true);
|
await form.setInputValue('rollupIndexPattern', 'unknown', true);
|
||||||
actions.clickNextStep();
|
actions.clickNextStep();
|
||||||
expect(form.getErrorsMessages()).toContain("Index pattern doesn't match any indices.");
|
expect(form.getErrorsMessages()).toContain("Index pattern doesn't match any indices.");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow an index pattern without time fields', async () => {
|
it('should not allow an index pattern without time fields', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ dateFields: [] });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { dateFields: [] } });
|
||||||
await form.setInputValue('rollupIndexPattern', 'abc', true);
|
await form.setInputValue('rollupIndexPattern', 'abc', true);
|
||||||
actions.clickNextStep();
|
actions.clickNextStep();
|
||||||
expect(form.getErrorsMessages()).toContain(
|
expect(form.getErrorsMessages()).toContain(
|
||||||
|
@ -110,7 +113,9 @@ describe('Create Rollup Job, step 1: Logistics', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow an index pattern that matches a rollup index', async () => {
|
it('should not allow an index pattern that matches a rollup index', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ doesMatchRollupIndices: true });
|
mockHttpRequest(npStart.core.http, {
|
||||||
|
indxPatternVldtResp: { doesMatchRollupIndices: true },
|
||||||
|
});
|
||||||
await form.setInputValue('rollupIndexPattern', 'abc', true);
|
await form.setInputValue('rollupIndexPattern', 'abc', true);
|
||||||
actions.clickNextStep();
|
actions.clickNextStep();
|
||||||
expect(form.getErrorsMessages()).toContain('Index pattern must not match rollup indices.');
|
expect(form.getErrorsMessages()).toContain('Index pattern must not match rollup indices.');
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setupEnvironment, pageHelpers } from './helpers';
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
|
import { mockHttpRequest, pageHelpers } from './helpers';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
|
||||||
|
@ -13,8 +14,6 @@ jest.mock('lodash/function/debounce', () => fn => fn);
|
||||||
const { setup } = pageHelpers.jobCreate;
|
const { setup } = pageHelpers.jobCreate;
|
||||||
|
|
||||||
describe('Create Rollup Job, step 5: Metrics', () => {
|
describe('Create Rollup Job, step 5: Metrics', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let find;
|
let find;
|
||||||
let exists;
|
let exists;
|
||||||
let actions;
|
let actions;
|
||||||
|
@ -22,22 +21,26 @@ describe('Create Rollup Job, step 5: Metrics', () => {
|
||||||
let goToStep;
|
let goToStep;
|
||||||
let table;
|
let table;
|
||||||
let metrics;
|
let metrics;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
});
|
setHttp(npStart.core.http);
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set "default" mock responses by not providing any arguments
|
// Set "default" mock responses by not providing any arguments
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse();
|
mockHttpRequest(npStart.core.http);
|
||||||
|
|
||||||
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table, metrics } = setup());
|
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table, metrics } = setup());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
npStart.core.http.post.mockClear();
|
||||||
|
npStart.core.http.put.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
const numericFields = ['a-numericField', 'c-numericField'];
|
const numericFields = ['a-numericField', 'c-numericField'];
|
||||||
const dateFields = ['b-dateField', 'd-dateField'];
|
const dateFields = ['b-dateField', 'd-dateField'];
|
||||||
|
|
||||||
|
@ -109,7 +112,7 @@ describe('Create Rollup Job, step 5: Metrics', () => {
|
||||||
|
|
||||||
describe('table', () => {
|
describe('table', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields, dateFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields, dateFields } });
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -166,7 +169,7 @@ describe('Create Rollup Job, step 5: Metrics', () => {
|
||||||
|
|
||||||
describe('when fields are added', () => {
|
describe('when fields are added', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields, dateFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields, dateFields } });
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -257,7 +260,8 @@ describe('Create Rollup Job, step 5: Metrics', () => {
|
||||||
let getFieldListTableRows;
|
let getFieldListTableRows;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields, dateFields });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields, dateFields } });
|
||||||
|
|
||||||
await goToStep(5);
|
await goToStep(5);
|
||||||
await addFieldToList('numeric');
|
await addFieldToList('numeric');
|
||||||
await addFieldToList('date');
|
await addFieldToList('date');
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setupEnvironment, pageHelpers } from './helpers';
|
import { pageHelpers, mockHttpRequest } from './helpers';
|
||||||
import { first } from 'lodash';
|
import { first } from 'lodash';
|
||||||
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
import { JOBS } from './helpers/constants';
|
import { JOBS } from './helpers/constants';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
@ -15,8 +16,6 @@ jest.mock('lodash/function/debounce', () => fn => fn);
|
||||||
const { setup } = pageHelpers.jobCreate;
|
const { setup } = pageHelpers.jobCreate;
|
||||||
|
|
||||||
describe('Create Rollup Job, step 6: Review', () => {
|
describe('Create Rollup Job, step 6: Review', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let find;
|
let find;
|
||||||
let exists;
|
let exists;
|
||||||
let actions;
|
let actions;
|
||||||
|
@ -24,21 +23,25 @@ describe('Create Rollup Job, step 6: Review', () => {
|
||||||
let goToStep;
|
let goToStep;
|
||||||
let table;
|
let table;
|
||||||
let form;
|
let form;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
});
|
setHttp(npStart.core.http);
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set "default" mock responses by not providing any arguments
|
// Set "default" mock responses by not providing any arguments
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse();
|
mockHttpRequest(npStart.core.http);
|
||||||
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table, form } = setup());
|
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table, form } = setup());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
npStart.core.http.post.mockClear();
|
||||||
|
npStart.core.http.put.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
describe('layout', () => {
|
describe('layout', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await goToStep(6);
|
await goToStep(6);
|
||||||
|
@ -81,7 +84,7 @@ describe('Create Rollup Job, step 6: Review', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "Summary", "Terms" & "Request" tab if a term aggregation was added', async () => {
|
it('should have a "Summary", "Terms" & "Request" tab if a term aggregation was added', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields: ['my-field'] });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields: ['my-field'] } });
|
||||||
await goToStep(3);
|
await goToStep(3);
|
||||||
selectFirstField('Terms');
|
selectFirstField('Terms');
|
||||||
|
|
||||||
|
@ -93,7 +96,7 @@ describe('Create Rollup Job, step 6: Review', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "Summary", "Histogram" & "Request" tab if a histogram field was added', async () => {
|
it('should have a "Summary", "Histogram" & "Request" tab if a histogram field was added', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields: ['a-field'] });
|
mockHttpRequest(npStart.core.http, { indxPatternVldtResp: { numericFields: ['a-field'] } });
|
||||||
await goToStep(4);
|
await goToStep(4);
|
||||||
selectFirstField('Histogram');
|
selectFirstField('Histogram');
|
||||||
form.setInputValue('rollupJobCreateHistogramInterval', 3); // set an interval
|
form.setInputValue('rollupJobCreateHistogramInterval', 3); // set an interval
|
||||||
|
@ -105,9 +108,11 @@ describe('Create Rollup Job, step 6: Review', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a "Summary", "Metrics" & "Request" tab if a histogram field was added', async () => {
|
it('should have a "Summary", "Metrics" & "Request" tab if a histogram field was added', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({
|
mockHttpRequest(npStart.core.http, {
|
||||||
numericFields: ['a-field'],
|
indxPatternVldtResp: {
|
||||||
dateFields: ['b-field'],
|
numericFields: ['a-field'],
|
||||||
|
dateFields: ['b-field'],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await goToStep(5);
|
await goToStep(5);
|
||||||
selectFirstField('Metrics');
|
selectFirstField('Metrics');
|
||||||
|
@ -125,27 +130,30 @@ describe('Create Rollup Job, step 6: Review', () => {
|
||||||
|
|
||||||
describe('without starting job after creation', () => {
|
describe('without starting job after creation', () => {
|
||||||
it('should call the "create" Api server endpoint', async () => {
|
it('should call the "create" Api server endpoint', async () => {
|
||||||
httpRequestsMockHelpers.setCreateJobResponse(first(JOBS.jobs));
|
mockHttpRequest(npStart.core.http, {
|
||||||
|
createdJob: first(JOBS.jobs),
|
||||||
|
});
|
||||||
|
|
||||||
await goToStep(6);
|
await goToStep(6);
|
||||||
|
|
||||||
expect(server.requests.find(r => r.url === jobCreateApiPath)).toBe(undefined); // make sure it hasn't been called
|
expect(npStart.core.http.put).not.toHaveBeenCalledWith(jobCreateApiPath); // make sure it hasn't been called
|
||||||
expect(server.requests.find(r => r.url === jobStartApiPath)).toBe(undefined); // make sure it hasn't been called
|
expect(npStart.core.http.get).not.toHaveBeenCalledWith(jobStartApiPath); // make sure it hasn't been called
|
||||||
|
|
||||||
actions.clickSave();
|
actions.clickSave();
|
||||||
// Given the following anti-jitter sleep x-pack/legacy/plugins/rollup/public/crud_app/store/actions/create_job.js
|
// Given the following anti-jitter sleep x-pack/legacy/plugins/rollup/public/crud_app/store/actions/create_job.js
|
||||||
// we add a longer sleep here :(
|
// we add a longer sleep here :(
|
||||||
await new Promise(res => setTimeout(res, 750));
|
await new Promise(res => setTimeout(res, 750));
|
||||||
|
|
||||||
expect(server.requests.find(r => r.url === jobCreateApiPath)).not.toBe(undefined); // It has been called!
|
expect(npStart.core.http.put).toHaveBeenCalledWith(jobCreateApiPath, expect.anything()); // It has been called!
|
||||||
expect(server.requests.find(r => r.url === jobStartApiPath)).toBe(undefined); // It has still not been called!
|
expect(npStart.core.http.get).not.toHaveBeenCalledWith(jobStartApiPath); // It has still not been called!
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with starting job after creation', () => {
|
describe('with starting job after creation', () => {
|
||||||
it('should call the "create" and "start" Api server endpoints', async () => {
|
it('should call the "create" and "start" Api server endpoints', async () => {
|
||||||
httpRequestsMockHelpers.setCreateJobResponse(first(JOBS.jobs));
|
mockHttpRequest(npStart.core.http, {
|
||||||
httpRequestsMockHelpers.setStartJobResponse();
|
createdJob: first(JOBS.jobs),
|
||||||
|
});
|
||||||
|
|
||||||
await goToStep(6);
|
await goToStep(6);
|
||||||
|
|
||||||
|
@ -153,14 +161,14 @@ describe('Create Rollup Job, step 6: Review', () => {
|
||||||
target: { checked: true },
|
target: { checked: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(server.requests.find(r => r.url === jobStartApiPath)).toBe(undefined); // make sure it hasn't been called
|
expect(npStart.core.http.post).not.toHaveBeenCalledWith(jobStartApiPath); // make sure it hasn't been called
|
||||||
|
|
||||||
actions.clickSave();
|
actions.clickSave();
|
||||||
// Given the following anti-jitter sleep x-pack/legacy/plugins/rollup/public/crud_app/store/actions/create_job.js
|
// Given the following anti-jitter sleep x-pack/legacy/plugins/rollup/public/crud_app/store/actions/create_job.js
|
||||||
// we add a longer sleep here :(
|
// we add a longer sleep here :(
|
||||||
await new Promise(res => setTimeout(res, 750));
|
await new Promise(res => setTimeout(res, 750));
|
||||||
|
|
||||||
expect(server.requests.find(r => r.url === jobStartApiPath)).not.toBe(undefined); // It has been called!
|
expect(npStart.core.http.post).toHaveBeenCalledWith(jobStartApiPath, expect.anything()); // It has been called!
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setupEnvironment, pageHelpers } from './helpers';
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
|
import { pageHelpers, mockHttpRequest } from './helpers';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
|
||||||
|
@ -13,30 +14,30 @@ jest.mock('lodash/function/debounce', () => fn => fn);
|
||||||
const { setup } = pageHelpers.jobCreate;
|
const { setup } = pageHelpers.jobCreate;
|
||||||
|
|
||||||
describe('Create Rollup Job, step 3: Terms', () => {
|
describe('Create Rollup Job, step 3: Terms', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let find;
|
let find;
|
||||||
let exists;
|
let exists;
|
||||||
let actions;
|
let actions;
|
||||||
let getEuiStepsHorizontalActive;
|
let getEuiStepsHorizontalActive;
|
||||||
let goToStep;
|
let goToStep;
|
||||||
let table;
|
let table;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
});
|
setHttp(npStart.core.http);
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set "default" mock responses by not providing any arguments
|
// Set "default" mock responses by not providing any arguments
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse();
|
mockHttpRequest(npStart.core.http);
|
||||||
|
|
||||||
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table } = setup());
|
({ find, exists, actions, getEuiStepsHorizontalActive, goToStep, table } = setup());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
const numericFields = ['a-numericField', 'c-numericField'];
|
const numericFields = ['a-numericField', 'c-numericField'];
|
||||||
const keywordFields = ['b-keywordField', 'd-keywordField'];
|
const keywordFields = ['b-keywordField', 'd-keywordField'];
|
||||||
|
|
||||||
|
@ -108,9 +109,11 @@ describe('Create Rollup Job, step 3: Terms', () => {
|
||||||
|
|
||||||
describe('when no terms are available', () => {
|
describe('when no terms are available', () => {
|
||||||
it('should indicate it to the user', async () => {
|
it('should indicate it to the user', async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({
|
mockHttpRequest(npStart.core.http, {
|
||||||
numericFields: [],
|
indxPatternVldtResp: {
|
||||||
keywordFields: [],
|
numericFields: [],
|
||||||
|
keywordFields: [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
|
|
||||||
|
@ -122,7 +125,12 @@ describe('Create Rollup Job, step 3: Terms', () => {
|
||||||
|
|
||||||
describe('when terms are available', () => {
|
describe('when terms are available', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields, keywordFields });
|
mockHttpRequest(npStart.core.http, {
|
||||||
|
indxPatternVldtResp: {
|
||||||
|
numericFields,
|
||||||
|
keywordFields,
|
||||||
|
},
|
||||||
|
});
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -163,7 +171,12 @@ describe('Create Rollup Job, step 3: Terms', () => {
|
||||||
|
|
||||||
it('should have a delete button on each row to remove a term', async () => {
|
it('should have a delete button on each row to remove a term', async () => {
|
||||||
// First let's add a term to the list
|
// First let's add a term to the list
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse({ numericFields, keywordFields });
|
mockHttpRequest(npStart.core.http, {
|
||||||
|
indxPatternVldtResp: {
|
||||||
|
numericFields,
|
||||||
|
keywordFields,
|
||||||
|
},
|
||||||
|
});
|
||||||
await goToStepAndOpenFieldChooser();
|
await goToStepAndOpenFieldChooser();
|
||||||
const { rows: fieldChooserRows } = table.getMetaData('rollupJobTermsFieldChooser-table');
|
const { rows: fieldChooserRows } = table.getMetaData('rollupJobTermsFieldChooser-table');
|
||||||
fieldChooserRows[0].reactWrapper.simulate('click');
|
fieldChooserRows[0].reactWrapper.simulate('click');
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { getRouter } from '../../public/crud_app/services';
|
import { getRouter, setHttp } from '../../public/crud_app/services';
|
||||||
import { setupEnvironment, pageHelpers, nextTick } from './helpers';
|
import { mockHttpRequest, pageHelpers, nextTick } from './helpers';
|
||||||
import { JOBS } from './helpers/constants';
|
import { JOBS } from './helpers/constants';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
@ -22,22 +22,18 @@ const { setup } = pageHelpers.jobList;
|
||||||
|
|
||||||
describe('<JobList />', () => {
|
describe('<JobList />', () => {
|
||||||
describe('detail panel', () => {
|
describe('detail panel', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let component;
|
let component;
|
||||||
let table;
|
let table;
|
||||||
let exists;
|
let exists;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
});
|
setHttp(npStart.core.http);
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setLoadJobsResponse(JOBS);
|
mockHttpRequest(npStart.core.http, { jobs: JOBS });
|
||||||
|
|
||||||
({ component, exists, table } = setup());
|
({ component, exists, table } = setup());
|
||||||
|
|
||||||
|
@ -45,6 +41,10 @@ describe('<JobList />', () => {
|
||||||
component.update();
|
component.update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
test('should open the detail panel when clicking on a job in the table', () => {
|
test('should open the detail panel when clicking on a job in the table', () => {
|
||||||
const { rows } = table.getMetaData('rollupJobsListTable');
|
const { rows } = table.getMetaData('rollupJobsListTable');
|
||||||
const button = rows[0].columns[1].reactWrapper.find('button');
|
const button = rows[0].columns[1].reactWrapper.find('button');
|
||||||
|
|
|
@ -4,9 +4,10 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { setupEnvironment, pageHelpers, nextTick } from './helpers';
|
import { mockHttpRequest, pageHelpers, nextTick } from './helpers';
|
||||||
import { JOB_TO_CLONE, JOB_CLONE_INDEX_PATTERN_CHECK } from './helpers/constants';
|
import { JOB_TO_CLONE, JOB_CLONE_INDEX_PATTERN_CHECK } from './helpers/constants';
|
||||||
import { getRouter } from '../../public/crud_app/services/routing';
|
import { getRouter } from '../../public/crud_app/services/routing';
|
||||||
|
import { setHttp } from '../../public/crud_app/services';
|
||||||
import { CRUD_APP_BASE_PATH } from '../../public/crud_app/constants';
|
import { CRUD_APP_BASE_PATH } from '../../public/crud_app/constants';
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
|
@ -16,24 +17,22 @@ jest.mock('lodash/function/debounce', () => fn => fn);
|
||||||
const { setup } = pageHelpers.jobList;
|
const { setup } = pageHelpers.jobList;
|
||||||
|
|
||||||
describe('Smoke test cloning an existing rollup job from job list', () => {
|
describe('Smoke test cloning an existing rollup job from job list', () => {
|
||||||
let server;
|
|
||||||
let httpRequestsMockHelpers;
|
|
||||||
let table;
|
let table;
|
||||||
let find;
|
let find;
|
||||||
let component;
|
let component;
|
||||||
let exists;
|
let exists;
|
||||||
|
let npStart;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
({ server, httpRequestsMockHelpers } = setupEnvironment());
|
npStart = require('ui/new_platform').npStart; // eslint-disable-line
|
||||||
});
|
setHttp(npStart.core.http);
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
server.restore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setIndexPatternValidityResponse(JOB_CLONE_INDEX_PATTERN_CHECK);
|
mockHttpRequest(npStart.core.http, {
|
||||||
httpRequestsMockHelpers.setLoadJobsResponse(JOB_TO_CLONE);
|
jobs: JOB_TO_CLONE,
|
||||||
|
indxPatternVldtResp: JOB_CLONE_INDEX_PATTERN_CHECK,
|
||||||
|
});
|
||||||
|
|
||||||
({ find, exists, table, component } = setup());
|
({ find, exists, table, component } = setup());
|
||||||
|
|
||||||
|
@ -41,6 +40,10 @@ describe('Smoke test cloning an existing rollup job from job list', () => {
|
||||||
component.update();
|
component.update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
npStart.core.http.get.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
it('should navigate to create view with default values set', async () => {
|
it('should navigate to create view with default values set', async () => {
|
||||||
const router = getRouter();
|
const router = getRouter();
|
||||||
const { rows } = table.getMetaData('rollupJobsListTable');
|
const { rows } = table.getMetaData('rollupJobsListTable');
|
||||||
|
|
|
@ -26,7 +26,7 @@ export function rollup(kibana) {
|
||||||
require: ['kibana', 'elasticsearch', 'xpack_main'],
|
require: ['kibana', 'elasticsearch', 'xpack_main'],
|
||||||
uiExports: {
|
uiExports: {
|
||||||
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
|
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
|
||||||
managementSections: ['plugins/rollup/crud_app'],
|
managementSections: ['plugins/rollup/legacy'],
|
||||||
uiSettingDefaults: {
|
uiSettingDefaults: {
|
||||||
[CONFIG_ROLLUPS]: {
|
[CONFIG_ROLLUPS]: {
|
||||||
name: i18n.translate('xpack.rollupJobs.rollupIndexPatternsTitle', {
|
name: i18n.translate('xpack.rollupJobs.rollupIndexPatternsTitle', {
|
||||||
|
@ -41,13 +41,9 @@ export function rollup(kibana) {
|
||||||
category: ['rollups'],
|
category: ['rollups'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
indexManagement: [
|
indexManagement: ['plugins/rollup/legacy'],
|
||||||
'plugins/rollup/index_pattern_creation',
|
visualize: ['plugins/rollup/legacy'],
|
||||||
'plugins/rollup/index_pattern_list',
|
search: ['plugins/rollup/legacy'],
|
||||||
'plugins/rollup/extend_index_management',
|
|
||||||
],
|
|
||||||
visualize: ['plugins/rollup/visualize'],
|
|
||||||
search: ['plugins/rollup/search'],
|
|
||||||
},
|
},
|
||||||
init: function(server) {
|
init: function(server) {
|
||||||
const { usageCollection } = server.newPlatform.setup.plugins;
|
const { usageCollection } = server.newPlatform.setup.plugins;
|
||||||
|
|
47
x-pack/legacy/plugins/rollup/public/application.tsx
Normal file
47
x-pack/legacy/plugins/rollup/public/application.tsx
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { render, unmountComponentAtNode } from 'react-dom';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
|
||||||
|
import { ChromeBreadcrumb, CoreSetup } from '../../../../../src/core/public';
|
||||||
|
// @ts-ignore
|
||||||
|
import { rollupJobsStore } from './crud_app/store';
|
||||||
|
// @ts-ignore
|
||||||
|
import { App } from './crud_app/app';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module will be loaded asynchronously to reduce the bundle size of your plugin's main bundle.
|
||||||
|
*/
|
||||||
|
export const renderApp = async (
|
||||||
|
core: CoreSetup,
|
||||||
|
{
|
||||||
|
element,
|
||||||
|
setBreadcrumbs,
|
||||||
|
}: { element: HTMLElement; setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void }
|
||||||
|
) => {
|
||||||
|
const [coreStart] = await core.getStartServices();
|
||||||
|
const I18nContext = coreStart.i18n.Context;
|
||||||
|
|
||||||
|
render(
|
||||||
|
<I18nContext>
|
||||||
|
<KibanaContextProvider
|
||||||
|
services={{
|
||||||
|
setBreadcrumbs,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Provider store={rollupJobsStore}>
|
||||||
|
<App />
|
||||||
|
</Provider>
|
||||||
|
</KibanaContextProvider>
|
||||||
|
</I18nContext>,
|
||||||
|
element
|
||||||
|
);
|
||||||
|
return () => {
|
||||||
|
unmountComponentAtNode(element);
|
||||||
|
};
|
||||||
|
};
|
|
@ -5,10 +5,6 @@
|
||||||
align-items: flex-end; /* 1 */
|
align-items: flex-end; /* 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.rollupJobsRoot {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. Ensure panel fills width of parent when search input yields no matching rollup jobs.
|
* 1. Ensure panel fills width of parent when search input yields no matching rollup jobs.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import {
|
|
||||||
FeatureCatalogueRegistryProvider,
|
|
||||||
FeatureCatalogueCategory,
|
|
||||||
} from 'ui/registry/feature_catalogue';
|
|
||||||
import { render, unmountComponentAtNode } from 'react-dom';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
import { i18n } from '@kbn/i18n';
|
|
||||||
import { I18nContext } from 'ui/i18n';
|
|
||||||
import { management } from 'ui/management';
|
|
||||||
import routes from 'ui/routes';
|
|
||||||
|
|
||||||
import { CRUD_APP_BASE_PATH } from './constants';
|
|
||||||
import { setHttp, setUserHasLeftApp } from './services';
|
|
||||||
import { App } from './app';
|
|
||||||
import template from './main.html';
|
|
||||||
import { rollupJobsStore } from './store';
|
|
||||||
|
|
||||||
const esSection = management.getSection('elasticsearch');
|
|
||||||
|
|
||||||
esSection.register('rollup_jobs', {
|
|
||||||
visible: true,
|
|
||||||
display: i18n.translate('xpack.rollupJobs.appTitle', { defaultMessage: 'Rollup Jobs' }),
|
|
||||||
order: 3,
|
|
||||||
url: `#${CRUD_APP_BASE_PATH}/job_list`,
|
|
||||||
});
|
|
||||||
|
|
||||||
const renderReact = async elem => {
|
|
||||||
render(
|
|
||||||
<I18nContext>
|
|
||||||
<Provider store={rollupJobsStore}>
|
|
||||||
<App />
|
|
||||||
</Provider>
|
|
||||||
</I18nContext>,
|
|
||||||
elem
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
routes.when(`${CRUD_APP_BASE_PATH}/:view?`, {
|
|
||||||
template: template,
|
|
||||||
controllerAs: 'rollupJobs',
|
|
||||||
controller: class IndexRollupJobsController {
|
|
||||||
constructor($scope, $route, $injector) {
|
|
||||||
// NOTE: We depend upon Angular's $http service because it's decorated with interceptors,
|
|
||||||
// e.g. to check license status per request.
|
|
||||||
setHttp($injector.get('$http'));
|
|
||||||
|
|
||||||
// If returning to the app, we'll need to reset this state.
|
|
||||||
setUserHasLeftApp(false);
|
|
||||||
|
|
||||||
$scope.$$postDigest(() => {
|
|
||||||
const appElement = document.getElementById('rollupJobsReactRoot');
|
|
||||||
renderReact(appElement);
|
|
||||||
|
|
||||||
const appRoute = $route.current;
|
|
||||||
const stopListeningForLocationChange = $scope.$on('$locationChangeSuccess', () => {
|
|
||||||
const currentRoute = $route.current;
|
|
||||||
|
|
||||||
const isNavigationInApp = currentRoute.$$route.template === appRoute.$$route.template;
|
|
||||||
|
|
||||||
// When we navigate within rollups, prevent Angular from re-matching the route and
|
|
||||||
// rebuilding the app.
|
|
||||||
if (isNavigationInApp) {
|
|
||||||
$route.current = appRoute;
|
|
||||||
} else {
|
|
||||||
// Set internal flag so we can prevent reacting to the route change internally.
|
|
||||||
setUserHasLeftApp(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.$on('$destroy', () => {
|
|
||||||
stopListeningForLocationChange();
|
|
||||||
unmountComponentAtNode(appElement);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
FeatureCatalogueRegistryProvider.register(() => {
|
|
||||||
return {
|
|
||||||
id: 'rollup_jobs',
|
|
||||||
title: 'Rollups',
|
|
||||||
description: i18n.translate('xpack.rollupJobs.featureCatalogueDescription', {
|
|
||||||
defaultMessage: 'Summarize and store historical data in a smaller index for future analysis.',
|
|
||||||
}),
|
|
||||||
icon: 'indexRollupApp',
|
|
||||||
path: `#${CRUD_APP_BASE_PATH}/job_list`,
|
|
||||||
showOnHomePage: true,
|
|
||||||
category: FeatureCatalogueCategory.ADMIN,
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,3 +0,0 @@
|
||||||
<kbn-management-app section="elasticsearch/rollup_jobs">
|
|
||||||
<div id="rollupJobsReactRoot" class="rollupJobsRoot"></div>
|
|
||||||
</kbn-management-app>
|
|
|
@ -6,11 +6,12 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui';
|
import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui';
|
||||||
|
|
||||||
class ConfirmDeleteModalUi extends Component {
|
export class ConfirmDeleteModal extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isSingleSelection: PropTypes.bool.isRequired,
|
isSingleSelection: PropTypes.bool.isRequired,
|
||||||
jobs: PropTypes.array.isRequired,
|
jobs: PropTypes.array.isRequired,
|
||||||
|
@ -19,12 +20,14 @@ class ConfirmDeleteModalUi extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
renderJobs() {
|
renderJobs() {
|
||||||
const { jobs, intl } = this.props;
|
const { jobs } = this.props;
|
||||||
const jobItems = jobs.map(({ id, status }) => {
|
const jobItems = jobs.map(({ id, status }) => {
|
||||||
const startedMessage = intl.formatMessage({
|
const startedMessage = i18n.translate(
|
||||||
id: 'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.startedMessage',
|
'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.startedMessage',
|
||||||
defaultMessage: 'started',
|
{
|
||||||
});
|
defaultMessage: 'started',
|
||||||
|
}
|
||||||
|
);
|
||||||
const statusText = status === 'started' ? ` (${startedMessage})` : null;
|
const statusText = status === 'started' ? ` (${startedMessage})` : null;
|
||||||
return (
|
return (
|
||||||
<li key={id}>
|
<li key={id}>
|
||||||
|
@ -38,19 +41,19 @@ class ConfirmDeleteModalUi extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isSingleSelection, jobs, onCancel, onConfirm, intl } = this.props;
|
const { isSingleSelection, jobs, onCancel, onConfirm } = this.props;
|
||||||
|
|
||||||
let title;
|
let title;
|
||||||
let content;
|
let content;
|
||||||
|
|
||||||
if (isSingleSelection) {
|
if (isSingleSelection) {
|
||||||
const { id, status } = jobs[0];
|
const { id, status } = jobs[0];
|
||||||
title = intl.formatMessage(
|
title = i18n.translate(
|
||||||
|
'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.deleteSingleJobTitle',
|
||||||
{
|
{
|
||||||
id: 'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.deleteSingleJobTitle',
|
|
||||||
defaultMessage: "Delete rollup job '{id}'?",
|
defaultMessage: "Delete rollup job '{id}'?",
|
||||||
},
|
values: { id },
|
||||||
{ id }
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (status === 'started') {
|
if (status === 'started') {
|
||||||
|
@ -64,12 +67,12 @@ class ConfirmDeleteModalUi extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
title = intl.formatMessage(
|
title = i18n.translate(
|
||||||
|
'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.multipleDeletionTitle',
|
||||||
{
|
{
|
||||||
id: 'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.multipleDeletionTitle',
|
|
||||||
defaultMessage: 'Delete {count} rollup jobs?',
|
defaultMessage: 'Delete {count} rollup jobs?',
|
||||||
},
|
values: { count: jobs.length },
|
||||||
{ count: jobs.length }
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
content = (
|
content = (
|
||||||
|
@ -92,15 +95,19 @@ class ConfirmDeleteModalUi extends Component {
|
||||||
title={title}
|
title={title}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
onConfirm={onConfirm}
|
onConfirm={onConfirm}
|
||||||
cancelButtonText={intl.formatMessage({
|
cancelButtonText={i18n.translate(
|
||||||
id: 'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.cancelButtonText',
|
'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.cancelButtonText',
|
||||||
defaultMessage: 'Cancel',
|
{
|
||||||
})}
|
defaultMessage: 'Cancel',
|
||||||
|
}
|
||||||
|
)}
|
||||||
buttonColor="danger"
|
buttonColor="danger"
|
||||||
confirmButtonText={intl.formatMessage({
|
confirmButtonText={i18n.translate(
|
||||||
id: 'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.confirmButtonText',
|
'xpack.rollupJobs.jobActionMenu.deleteJob.confirmModal.confirmButtonText',
|
||||||
defaultMessage: 'Delete',
|
{
|
||||||
})}
|
defaultMessage: 'Delete',
|
||||||
|
}
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
</EuiConfirmModal>
|
</EuiConfirmModal>
|
||||||
|
@ -108,5 +115,3 @@ class ConfirmDeleteModalUi extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConfirmDeleteModal = injectI18n(ConfirmDeleteModalUi);
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ import debounce from 'lodash/function/debounce';
|
||||||
import first from 'lodash/array/first';
|
import first from 'lodash/array/first';
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import chrome from 'ui/chrome';
|
|
||||||
import { MANAGEMENT_BREADCRUMB } from 'ui/management';
|
import { withKibana } from '../../../../../../../../src/plugins/kibana_react/public/';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiCallOut,
|
EuiCallOut,
|
||||||
|
@ -27,8 +27,6 @@ import {
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import { fatalError } from 'ui/notify';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
validateIndexPattern,
|
validateIndexPattern,
|
||||||
formatFields,
|
formatFields,
|
||||||
|
@ -59,6 +57,8 @@ import {
|
||||||
hasErrors,
|
hasErrors,
|
||||||
} from './steps_config';
|
} from './steps_config';
|
||||||
|
|
||||||
|
import { getFatalErrors } from '../../../kibana_services';
|
||||||
|
|
||||||
const stepIdToTitleMap = {
|
const stepIdToTitleMap = {
|
||||||
[STEP_LOGISTICS]: i18n.translate('xpack.rollupJobs.create.steps.stepLogisticsTitle', {
|
[STEP_LOGISTICS]: i18n.translate('xpack.rollupJobs.create.steps.stepLogisticsTitle', {
|
||||||
defaultMessage: 'Logistics',
|
defaultMessage: 'Logistics',
|
||||||
|
@ -92,7 +92,7 @@ export class JobCreateUi extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
chrome.breadcrumbs.set([MANAGEMENT_BREADCRUMB, listBreadcrumb, createBreadcrumb]);
|
props.kibana.services.setBreadcrumbs([listBreadcrumb, createBreadcrumb]);
|
||||||
const { jobToClone: stepDefaultOverrides } = props;
|
const { jobToClone: stepDefaultOverrides } = props;
|
||||||
const stepsFields = mapValues(stepIdToStepConfigMap, step =>
|
const stepsFields = mapValues(stepIdToStepConfigMap, step =>
|
||||||
cloneDeep(step.getDefaultFields(stepDefaultOverrides))
|
cloneDeep(step.getDefaultFields(stepDefaultOverrides))
|
||||||
|
@ -181,7 +181,7 @@ export class JobCreateUi extends Component {
|
||||||
dateFields: indexPatternDateFields,
|
dateFields: indexPatternDateFields,
|
||||||
numericFields,
|
numericFields,
|
||||||
keywordFields,
|
keywordFields,
|
||||||
} = response.data;
|
} = response;
|
||||||
|
|
||||||
let indexPatternAsyncErrors;
|
let indexPatternAsyncErrors;
|
||||||
|
|
||||||
|
@ -298,9 +298,9 @@ export class JobCreateUi extends Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expect an error in the shape provided by Angular's $http service.
|
// Expect an error in the shape provided by http service.
|
||||||
if (error && error.data) {
|
if (error && error.body) {
|
||||||
const { error: errorString, statusCode } = error.data;
|
const { error: errorString, statusCode } = error.body;
|
||||||
|
|
||||||
const indexPatternAsyncErrors = [
|
const indexPatternAsyncErrors = [
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
|
@ -324,7 +324,7 @@ export class JobCreateUi extends Component {
|
||||||
|
|
||||||
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
||||||
// unexpected happened.
|
// unexpected happened.
|
||||||
fatalError(
|
getFatalErrors().add(
|
||||||
error,
|
error,
|
||||||
i18n.translate('xpack.rollupJobs.create.errors.indexPatternValidationFatalErrorTitle', {
|
i18n.translate('xpack.rollupJobs.create.errors.indexPatternValidationFatalErrorTitle', {
|
||||||
defaultMessage: 'Rollup Job Wizard index pattern validation',
|
defaultMessage: 'Rollup Job Wizard index pattern validation',
|
||||||
|
@ -689,4 +689,4 @@ export class JobCreateUi extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const JobCreate = injectI18n(JobCreateUi);
|
export const JobCreate = withKibana(JobCreateUi);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiButton,
|
EuiButton,
|
||||||
|
@ -18,7 +18,7 @@ import {
|
||||||
EuiCheckbox,
|
EuiCheckbox,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
const NavigationUi = ({
|
export const Navigation = ({
|
||||||
isSaving,
|
isSaving,
|
||||||
hasNextStep,
|
hasNextStep,
|
||||||
hasPreviousStep,
|
hasPreviousStep,
|
||||||
|
@ -120,7 +120,7 @@ const NavigationUi = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
NavigationUi.propTypes = {
|
Navigation.propTypes = {
|
||||||
hasNextStep: PropTypes.bool.isRequired,
|
hasNextStep: PropTypes.bool.isRequired,
|
||||||
hasPreviousStep: PropTypes.bool.isRequired,
|
hasPreviousStep: PropTypes.bool.isRequired,
|
||||||
isSaving: PropTypes.bool.isRequired,
|
isSaving: PropTypes.bool.isRequired,
|
||||||
|
@ -129,5 +129,3 @@ NavigationUi.propTypes = {
|
||||||
save: PropTypes.func.isRequired,
|
save: PropTypes.func.isRequired,
|
||||||
canGoToNextStep: PropTypes.bool.isRequired,
|
canGoToNextStep: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Navigation = injectI18n(NavigationUi);
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -26,7 +26,7 @@ import {
|
||||||
|
|
||||||
import { parseEsInterval } from '../../../../../../../../../src/legacy/core_plugins/data/public';
|
import { parseEsInterval } from '../../../../../../../../../src/legacy/core_plugins/data/public';
|
||||||
|
|
||||||
import { dateHistogramDetailsUrl, dateHistogramAggregationUrl } from '../../../services';
|
import { getDateHistogramDetailsUrl, getDateHistogramAggregationUrl } from '../../../services';
|
||||||
|
|
||||||
import { StepError } from './components';
|
import { StepError } from './components';
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ const timeZoneOptions = moment.tz.names().map(name => ({
|
||||||
text: name,
|
text: name,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export class StepDateHistogramUi extends Component {
|
export class StepDateHistogram extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
fields: PropTypes.object.isRequired,
|
fields: PropTypes.object.isRequired,
|
||||||
onFieldsChange: PropTypes.func.isRequired,
|
onFieldsChange: PropTypes.func.isRequired,
|
||||||
|
@ -192,7 +192,7 @@ export class StepDateHistogramUi extends Component {
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
size="s"
|
size="s"
|
||||||
flush="right"
|
flush="right"
|
||||||
href={dateHistogramDetailsUrl}
|
href={getDateHistogramDetailsUrl()}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
iconType="help"
|
iconType="help"
|
||||||
data-test-subj="rollupJobCreateDateHistogramDocsButton"
|
data-test-subj="rollupJobCreateDateHistogramDocsButton"
|
||||||
|
@ -218,7 +218,7 @@ export class StepDateHistogramUi extends Component {
|
||||||
defaultMessage="Define how {link} will operate on your rollup data."
|
defaultMessage="Define how {link} will operate on your rollup data."
|
||||||
values={{
|
values={{
|
||||||
link: (
|
link: (
|
||||||
<EuiLink href={dateHistogramAggregationUrl} target="_blank">
|
<EuiLink href={getDateHistogramAggregationUrl()} target="_blank">
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="xpack.rollupJobs.create.stepDateHistogramDescription.aggregationsLinkLabel"
|
id="xpack.rollupJobs.create.stepDateHistogramDescription.aggregationsLinkLabel"
|
||||||
defaultMessage="date histogram aggregations"
|
defaultMessage="date histogram aggregations"
|
||||||
|
@ -318,5 +318,3 @@ export class StepDateHistogramUi extends Component {
|
||||||
return <StepError />;
|
return <StepError />;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StepDateHistogram = injectI18n(StepDateHistogramUi);
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiButtonEmpty,
|
EuiButtonEmpty,
|
||||||
|
@ -20,13 +20,13 @@ import {
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import { histogramDetailsUrl } from '../../../services';
|
import { getHistogramDetailsUrl } from '../../../services';
|
||||||
|
|
||||||
import { FieldList } from '../../components';
|
import { FieldList } from '../../components';
|
||||||
|
|
||||||
import { FieldChooser, StepError } from './components';
|
import { FieldChooser, StepError } from './components';
|
||||||
|
|
||||||
export class StepHistogramUi extends Component {
|
export class StepHistogram extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
fields: PropTypes.object.isRequired,
|
fields: PropTypes.object.isRequired,
|
||||||
onFieldsChange: PropTypes.func.isRequired,
|
onFieldsChange: PropTypes.func.isRequired,
|
||||||
|
@ -96,7 +96,7 @@ export class StepHistogramUi extends Component {
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
size="s"
|
size="s"
|
||||||
flush="right"
|
flush="right"
|
||||||
href={histogramDetailsUrl}
|
href={getHistogramDetailsUrl()}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
iconType="help"
|
iconType="help"
|
||||||
data-test-subj="rollupJobCreateHistogramDocsButton"
|
data-test-subj="rollupJobCreateHistogramDocsButton"
|
||||||
|
@ -212,5 +212,3 @@ export class StepHistogramUi extends Component {
|
||||||
return <StepError />;
|
return <StepError />;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StepHistogram = injectI18n(StepHistogramUi);
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiButtonEmpty,
|
EuiButtonEmpty,
|
||||||
|
@ -26,8 +26,8 @@ import {
|
||||||
|
|
||||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||||
import { CronEditor } from '../../../../../../../../../src/plugins/es_ui_shared/public/components/cron_editor';
|
import { CronEditor } from '../../../../../../../../../src/plugins/es_ui_shared/public/components/cron_editor';
|
||||||
import { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from 'ui/indices';
|
import { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from '../../../../legacy_imports';
|
||||||
import { logisticalDetailsUrl, cronUrl } from '../../../services';
|
import { getLogisticalDetailsUrl, getCronUrl } from '../../../services';
|
||||||
import { StepError } from './components';
|
import { StepError } from './components';
|
||||||
|
|
||||||
import { indexPatterns } from '../../../../../../../../../src/plugins/data/public';
|
import { indexPatterns } from '../../../../../../../../../src/plugins/data/public';
|
||||||
|
@ -35,7 +35,7 @@ import { indexPatterns } from '../../../../../../../../../src/plugins/data/publi
|
||||||
const indexPatternIllegalCharacters = indexPatterns.ILLEGAL_CHARACTERS_VISIBLE.join(' ');
|
const indexPatternIllegalCharacters = indexPatterns.ILLEGAL_CHARACTERS_VISIBLE.join(' ');
|
||||||
const indexIllegalCharacters = INDEX_ILLEGAL_CHARACTERS_VISIBLE.join(' ');
|
const indexIllegalCharacters = INDEX_ILLEGAL_CHARACTERS_VISIBLE.join(' ');
|
||||||
|
|
||||||
export class StepLogisticsUi extends Component {
|
export class StepLogistics extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
fields: PropTypes.object.isRequired,
|
fields: PropTypes.object.isRequired,
|
||||||
onFieldsChange: PropTypes.func.isRequired,
|
onFieldsChange: PropTypes.func.isRequired,
|
||||||
|
@ -146,7 +146,7 @@ export class StepLogisticsUi extends Component {
|
||||||
isInvalid={Boolean(areStepErrorsVisible && errorRollupCron)}
|
isInvalid={Boolean(areStepErrorsVisible && errorRollupCron)}
|
||||||
helpText={
|
helpText={
|
||||||
<p>
|
<p>
|
||||||
<EuiLink href={cronUrl} target="_blank">
|
<EuiLink href={getCronUrl()} target="_blank">
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="xpack.rollupJobs.create.stepLogistics.fieldCron.helpReferenceLinkLabel"
|
id="xpack.rollupJobs.create.stepLogistics.fieldCron.helpReferenceLinkLabel"
|
||||||
defaultMessage="Learn more about cron expressions"
|
defaultMessage="Learn more about cron expressions"
|
||||||
|
@ -258,7 +258,7 @@ export class StepLogisticsUi extends Component {
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
size="s"
|
size="s"
|
||||||
flush="right"
|
flush="right"
|
||||||
href={logisticalDetailsUrl}
|
href={getLogisticalDetailsUrl()}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
iconType="help"
|
iconType="help"
|
||||||
data-test-subj="rollupJobCreateLogisticsDocsButton"
|
data-test-subj="rollupJobCreateLogisticsDocsButton"
|
||||||
|
@ -522,5 +522,3 @@ export class StepLogisticsUi extends Component {
|
||||||
return <StepError />;
|
return <StepError />;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StepLogistics = injectI18n(StepLogisticsUi);
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import get from 'lodash/object/get';
|
import get from 'lodash/object/get';
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import {
|
||||||
EuiButton,
|
EuiButton,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import { metricsDetailsUrl } from '../../../services';
|
import { getMetricsDetailsUrl } from '../../../services';
|
||||||
import { FieldList } from '../../components';
|
import { FieldList } from '../../components';
|
||||||
import { FieldChooser, StepError } from './components';
|
import { FieldChooser, StepError } from './components';
|
||||||
import { METRICS_CONFIG } from '../../../constants';
|
import { METRICS_CONFIG } from '../../../constants';
|
||||||
|
@ -64,7 +64,7 @@ const metricTypesConfig = (function() {
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export class StepMetricsUi extends Component {
|
export class StepMetrics extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
fields: PropTypes.object.isRequired,
|
fields: PropTypes.object.isRequired,
|
||||||
onFieldsChange: PropTypes.func.isRequired,
|
onFieldsChange: PropTypes.func.isRequired,
|
||||||
|
@ -247,7 +247,7 @@ export class StepMetricsUi extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
getListColumns() {
|
getListColumns() {
|
||||||
return StepMetricsUi.chooserColumns.concat({
|
return StepMetrics.chooserColumns.concat({
|
||||||
type: 'metrics',
|
type: 'metrics',
|
||||||
name: i18n.translate('xpack.rollupJobs.create.stepMetrics.metricsColumnHeader', {
|
name: i18n.translate('xpack.rollupJobs.create.stepMetrics.metricsColumnHeader', {
|
||||||
defaultMessage: 'Metrics',
|
defaultMessage: 'Metrics',
|
||||||
|
@ -384,7 +384,7 @@ export class StepMetricsUi extends Component {
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
size="s"
|
size="s"
|
||||||
flush="right"
|
flush="right"
|
||||||
href={metricsDetailsUrl}
|
href={getMetricsDetailsUrl()}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
iconType="help"
|
iconType="help"
|
||||||
data-test-subj="rollupJobCreateMetricsDocsButton"
|
data-test-subj="rollupJobCreateMetricsDocsButton"
|
||||||
|
@ -421,7 +421,7 @@ export class StepMetricsUi extends Component {
|
||||||
defaultMessage="Add metrics fields"
|
defaultMessage="Add metrics fields"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
columns={StepMetricsUi.chooserColumns}
|
columns={StepMetrics.chooserColumns}
|
||||||
fields={metricsFields}
|
fields={metricsFields}
|
||||||
selectedFields={metrics}
|
selectedFields={metrics}
|
||||||
onSelectField={this.onSelectField}
|
onSelectField={this.onSelectField}
|
||||||
|
@ -472,5 +472,3 @@ export class StepMetricsUi extends Component {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StepMetrics = injectI18n(StepMetricsUi);
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import { EuiErrorBoundary, EuiSpacer, EuiTab, EuiTabs, EuiTitle } from '@elastic/eui';
|
import { EuiErrorBoundary, EuiSpacer, EuiTab, EuiTabs, EuiTitle } from '@elastic/eui';
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ const JOB_DETAILS_TABS = [
|
||||||
JOB_DETAILS_TAB_REQUEST,
|
JOB_DETAILS_TAB_REQUEST,
|
||||||
];
|
];
|
||||||
|
|
||||||
export class StepReviewUi extends Component {
|
export class StepReview extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
job: PropTypes.object.isRequired,
|
job: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -121,5 +121,3 @@ export class StepReviewUi extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StepReview = injectI18n(StepReviewUi);
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiButtonEmpty,
|
EuiButtonEmpty,
|
||||||
|
@ -17,13 +17,13 @@ import {
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import { termsDetailsUrl } from '../../../services';
|
import { getTermsDetailsUrl } from '../../../services';
|
||||||
|
|
||||||
import { FieldList } from '../../components';
|
import { FieldList } from '../../components';
|
||||||
|
|
||||||
import { FieldChooser } from './components';
|
import { FieldChooser } from './components';
|
||||||
|
|
||||||
export class StepTermsUi extends Component {
|
export class StepTerms extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
fields: PropTypes.object.isRequired,
|
fields: PropTypes.object.isRequired,
|
||||||
onFieldsChange: PropTypes.func.isRequired,
|
onFieldsChange: PropTypes.func.isRequired,
|
||||||
|
@ -99,7 +99,7 @@ export class StepTermsUi extends Component {
|
||||||
<EuiButtonEmpty
|
<EuiButtonEmpty
|
||||||
size="s"
|
size="s"
|
||||||
flush="right"
|
flush="right"
|
||||||
href={termsDetailsUrl}
|
href={getTermsDetailsUrl()}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
iconType="help"
|
iconType="help"
|
||||||
data-test-subj="rollupJobCreateTermsDocsButton"
|
data-test-subj="rollupJobCreateTermsDocsButton"
|
||||||
|
@ -140,5 +140,3 @@ export class StepTermsUi extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StepTerms = injectI18n(StepTermsUi);
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { findIllegalCharactersInIndexName } from 'ui/indices';
|
import { findIllegalCharactersInIndexName } from '../../../../legacy_imports';
|
||||||
|
|
||||||
export function validateRollupIndex(rollupIndex, indexPattern) {
|
export function validateRollupIndex(rollupIndex, indexPattern) {
|
||||||
if (!rollupIndex || !rollupIndex.trim()) {
|
if (!rollupIndex || !rollupIndex.trim()) {
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiErrorBoundary,
|
EuiErrorBoundary,
|
||||||
|
@ -62,7 +63,7 @@ const tabToUiMetricMap = {
|
||||||
[JOB_DETAILS_TAB_JSON]: UIM_DETAIL_PANEL_JSON_TAB_CLICK,
|
[JOB_DETAILS_TAB_JSON]: UIM_DETAIL_PANEL_JSON_TAB_CLICK,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class DetailPanelUi extends Component {
|
export class DetailPanel extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
isLoading: PropTypes.bool,
|
isLoading: PropTypes.bool,
|
||||||
|
@ -130,7 +131,7 @@ export class DetailPanelUi extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderJob() {
|
renderJob() {
|
||||||
const { panelType, job, intl } = this.props;
|
const { panelType, job } = this.props;
|
||||||
|
|
||||||
const { status, documentsProcessed, pagesProcessed, rollupsIndexed, triggerCount, json } = job;
|
const { status, documentsProcessed, pagesProcessed, rollupsIndexed, triggerCount, json } = job;
|
||||||
|
|
||||||
|
@ -159,8 +160,7 @@ export class DetailPanelUi extends Component {
|
||||||
anchorPosition="upRight"
|
anchorPosition="upRight"
|
||||||
detailPanel={true}
|
detailPanel={true}
|
||||||
iconType="arrowUp"
|
iconType="arrowUp"
|
||||||
label={intl.formatMessage({
|
label={i18n.translate('xpack.rollupJobs.detailPanel.jobActionMenu.buttonLabel', {
|
||||||
id: 'xpack.rollupJobs.detailPanel.jobActionMenu.buttonLabel',
|
|
||||||
defaultMessage: 'Manage',
|
defaultMessage: 'Manage',
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
@ -251,5 +251,3 @@ export class DetailPanelUi extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DetailPanel = injectI18n(DetailPanelUi);
|
|
||||||
|
|
|
@ -58,12 +58,12 @@ describe('<DetailPanel />', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should have children if it's open", () => {
|
it("should have children if it's open", () => {
|
||||||
expect(component.find('DetailPanelUi').children().length).toBeTruthy();
|
expect(component.find('DetailPanel').children().length).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should *not* have children if its closed', () => {
|
it('should *not* have children if its closed', () => {
|
||||||
({ component } = initTestBed({ isOpen: false }));
|
({ component } = initTestBed({ isOpen: false }));
|
||||||
expect(component.find('DetailPanelUi').children().length).toBeFalsy();
|
expect(component.find('DetailPanel').children().length).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show a loading when the job is loading', () => {
|
it('should show a loading when the job is loading', () => {
|
||||||
|
|
|
@ -6,9 +6,8 @@
|
||||||
|
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import chrome from 'ui/chrome';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { MANAGEMENT_BREADCRUMB } from 'ui/management';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiButton,
|
EuiButton,
|
||||||
|
@ -26,6 +25,8 @@ import {
|
||||||
EuiCallOut,
|
EuiCallOut,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
|
import { withKibana } from '../../../../../../../../src/plugins/kibana_react/public/';
|
||||||
|
|
||||||
import { CRUD_APP_BASE_PATH } from '../../constants';
|
import { CRUD_APP_BASE_PATH } from '../../constants';
|
||||||
import { getRouterLinkProps, extractQueryParams, listBreadcrumb } from '../../services';
|
import { getRouterLinkProps, extractQueryParams, listBreadcrumb } from '../../services';
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ export class JobListUi extends Component {
|
||||||
|
|
||||||
props.loadJobs();
|
props.loadJobs();
|
||||||
|
|
||||||
chrome.breadcrumbs.set([MANAGEMENT_BREADCRUMB, listBreadcrumb]);
|
props.kibana.services.setBreadcrumbs([listBreadcrumb]);
|
||||||
|
|
||||||
this.state = {};
|
this.state = {};
|
||||||
}
|
}
|
||||||
|
@ -97,9 +98,7 @@ export class JobListUi extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderNoPermission() {
|
renderNoPermission() {
|
||||||
const { intl } = this.props;
|
const title = i18n.translate('xpack.rollupJobs.jobList.noPermissionTitle', {
|
||||||
const title = intl.formatMessage({
|
|
||||||
id: 'xpack.rollupJobs.jobList.noPermissionTitle',
|
|
||||||
defaultMessage: 'Permission error',
|
defaultMessage: 'Permission error',
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
@ -122,13 +121,11 @@ export class JobListUi extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderError(error) {
|
renderError(error) {
|
||||||
// We can safely depend upon the shape of this error coming from Angular $http, because we
|
// We can safely depend upon the shape of this error coming from http service, because we
|
||||||
// handle unexpected error shapes in the API action.
|
// handle unexpected error shapes in the API action.
|
||||||
const { statusCode, error: errorString } = error.data;
|
const { statusCode, error: errorString } = error.body;
|
||||||
|
|
||||||
const { intl } = this.props;
|
const title = i18n.translate('xpack.rollupJobs.jobList.loadingErrorTitle', {
|
||||||
const title = intl.formatMessage({
|
|
||||||
id: 'xpack.rollupJobs.jobList.loadingErrorTitle',
|
|
||||||
defaultMessage: 'Error loading rollup jobs',
|
defaultMessage: 'Error loading rollup jobs',
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
|
@ -254,4 +251,4 @@ export class JobListUi extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const JobList = injectI18n(JobListUi);
|
export const JobList = withKibana(JobListUi);
|
||||||
|
|
|
@ -4,24 +4,16 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
import { registerTestBed } from '../../../../../../../test_utils';
|
import { registerTestBed } from '../../../../../../../test_utils';
|
||||||
import { rollupJobsStore } from '../../store';
|
import { rollupJobsStore } from '../../store';
|
||||||
import { JobList } from './job_list';
|
import { JobList } from './job_list';
|
||||||
|
|
||||||
|
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
import { coreMock } from '../../../../../../../../src/core/public/mocks';
|
||||||
|
const startMock = coreMock.createStart();
|
||||||
|
|
||||||
jest.mock('ui/new_platform');
|
jest.mock('ui/new_platform');
|
||||||
jest.mock('ui/chrome', () => ({
|
|
||||||
addBasePath: () => {},
|
|
||||||
breadcrumbs: { set: () => {} },
|
|
||||||
getInjected: key => {
|
|
||||||
if (key === 'uiCapabilities') {
|
|
||||||
return {
|
|
||||||
navLinks: {},
|
|
||||||
management: {},
|
|
||||||
catalogue: {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../../services', () => {
|
jest.mock('../../services', () => {
|
||||||
const services = require.requireActual('../../services');
|
const services = require.requireActual('../../services');
|
||||||
|
@ -40,7 +32,16 @@ const defaultProps = {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const initTestBed = registerTestBed(JobList, { defaultProps, store: rollupJobsStore });
|
const services = {
|
||||||
|
setBreadcrumbs: startMock.chrome.setBreadcrumbs,
|
||||||
|
};
|
||||||
|
const Component = props => (
|
||||||
|
<KibanaContextProvider services={services}>
|
||||||
|
<JobList {...props} />
|
||||||
|
</KibanaContextProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const initTestBed = registerTestBed(Component, { defaultProps, store: rollupJobsStore });
|
||||||
|
|
||||||
describe('<JobList />', () => {
|
describe('<JobList />', () => {
|
||||||
it('should render empty prompt when loading is complete and there are no jobs', () => {
|
it('should render empty prompt when loading is complete and there are no jobs', () => {
|
||||||
|
@ -53,21 +54,21 @@ describe('<JobList />', () => {
|
||||||
const { component, exists } = initTestBed({ isLoading: true });
|
const { component, exists } = initTestBed({ isLoading: true });
|
||||||
|
|
||||||
expect(exists('jobListLoading')).toBeTruthy();
|
expect(exists('jobListLoading')).toBeTruthy();
|
||||||
expect(component.find('JobTableUi').length).toBeFalsy();
|
expect(component.find('JobTable').length).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display the <JobTable /> when there are jobs', () => {
|
it('should display the <JobTable /> when there are jobs', () => {
|
||||||
const { component, exists } = initTestBed({ hasJobs: true });
|
const { component, exists } = initTestBed({ hasJobs: true });
|
||||||
|
|
||||||
expect(exists('jobListLoading')).toBeFalsy();
|
expect(exists('jobListLoading')).toBeFalsy();
|
||||||
expect(component.find('JobTableUi').length).toBeTruthy();
|
expect(component.find('JobTable').length).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when there is an API error', () => {
|
describe('when there is an API error', () => {
|
||||||
const { exists, find } = initTestBed({
|
const { exists, find } = initTestBed({
|
||||||
jobLoadError: {
|
jobLoadError: {
|
||||||
status: 400,
|
status: 400,
|
||||||
data: { statusCode: 400, error: 'Houston we got a problem.' },
|
body: { statusCode: 400, error: 'Houston we got a problem.' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EuiCheckbox,
|
EuiCheckbox,
|
||||||
|
@ -120,7 +120,7 @@ const COLUMNS = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export class JobTableUi extends Component {
|
export class JobTable extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
jobs: PropTypes.array,
|
jobs: PropTypes.array,
|
||||||
pager: PropTypes.object.isRequired,
|
pager: PropTypes.object.isRequired,
|
||||||
|
@ -333,7 +333,7 @@ export class JobTableUi extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { filterChanged, filter, jobs, intl, closeDetailPanel } = this.props;
|
const { filterChanged, filter, jobs, closeDetailPanel } = this.props;
|
||||||
|
|
||||||
const { idToSelectedJobMap } = this.state;
|
const { idToSelectedJobMap } = this.state;
|
||||||
|
|
||||||
|
@ -360,8 +360,7 @@ export class JobTableUi extends Component {
|
||||||
filterChanged(event.target.value);
|
filterChanged(event.target.value);
|
||||||
}}
|
}}
|
||||||
data-test-subj="jobTableFilterInput"
|
data-test-subj="jobTableFilterInput"
|
||||||
placeholder={intl.formatMessage({
|
placeholder={i18n.translate('xpack.rollupJobs.jobTable.searchInputPlaceholder', {
|
||||||
id: 'xpack.rollupJobs.jobTable.searchInputPlaceholder',
|
|
||||||
defaultMessage: 'Search',
|
defaultMessage: 'Search',
|
||||||
})}
|
})}
|
||||||
aria-label="Search jobs"
|
aria-label="Search jobs"
|
||||||
|
@ -405,5 +404,3 @@ export class JobTableUi extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const JobTable = injectI18n(JobTableUi);
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import chrome from 'ui/chrome';
|
|
||||||
import {
|
import {
|
||||||
UIM_JOB_CREATE,
|
UIM_JOB_CREATE,
|
||||||
UIM_JOB_DELETE,
|
UIM_JOB_DELETE,
|
||||||
|
@ -17,39 +16,45 @@ import {
|
||||||
import { getHttp } from './http_provider';
|
import { getHttp } from './http_provider';
|
||||||
import { trackUserRequest } from './track_ui_metric';
|
import { trackUserRequest } from './track_ui_metric';
|
||||||
|
|
||||||
const apiPrefix = chrome.addBasePath('/api/rollup');
|
const apiPrefix = '/api/rollup';
|
||||||
|
|
||||||
export async function loadJobs() {
|
export async function loadJobs() {
|
||||||
const {
|
const { jobs } = await getHttp().get(`${apiPrefix}/jobs`);
|
||||||
data: { jobs },
|
|
||||||
} = await getHttp().get(`${apiPrefix}/jobs`);
|
|
||||||
return jobs;
|
return jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function startJobs(jobIds) {
|
export async function startJobs(jobIds) {
|
||||||
const body = { jobIds };
|
const body = { jobIds };
|
||||||
const request = getHttp().post(`${apiPrefix}/start`, body);
|
const request = getHttp().post(`${apiPrefix}/start`, {
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
const actionType = jobIds.length > 1 ? UIM_JOB_START_MANY : UIM_JOB_START;
|
const actionType = jobIds.length > 1 ? UIM_JOB_START_MANY : UIM_JOB_START;
|
||||||
return await trackUserRequest(request, actionType);
|
return await trackUserRequest(request, actionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function stopJobs(jobIds) {
|
export async function stopJobs(jobIds) {
|
||||||
const body = { jobIds };
|
const body = { jobIds };
|
||||||
const request = getHttp().post(`${apiPrefix}/stop`, body);
|
const request = getHttp().post(`${apiPrefix}/stop`, {
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
const actionType = jobIds.length > 1 ? UIM_JOB_STOP_MANY : UIM_JOB_STOP;
|
const actionType = jobIds.length > 1 ? UIM_JOB_STOP_MANY : UIM_JOB_STOP;
|
||||||
return await trackUserRequest(request, actionType);
|
return await trackUserRequest(request, actionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteJobs(jobIds) {
|
export async function deleteJobs(jobIds) {
|
||||||
const body = { jobIds };
|
const body = { jobIds };
|
||||||
const request = getHttp().post(`${apiPrefix}/delete`, body);
|
const request = getHttp().post(`${apiPrefix}/delete`, {
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
const actionType = jobIds.length > 1 ? UIM_JOB_DELETE_MANY : UIM_JOB_DELETE;
|
const actionType = jobIds.length > 1 ? UIM_JOB_DELETE_MANY : UIM_JOB_DELETE;
|
||||||
return await trackUserRequest(request, actionType);
|
return await trackUserRequest(request, actionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createJob(job) {
|
export async function createJob(job) {
|
||||||
const body = { job };
|
const body = { job };
|
||||||
const request = getHttp().put(`${apiPrefix}/create`, body);
|
const request = getHttp().put(`${apiPrefix}/create`, {
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
return await trackUserRequest(request, UIM_JOB_CREATE);
|
return await trackUserRequest(request, UIM_JOB_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fatalError, toastNotifications } from 'ui/notify';
|
import { getNotifications, getFatalErrors } from '../../kibana_services';
|
||||||
|
|
||||||
function createToastConfig(error, errorTitle) {
|
function createToastConfig(error: any, errorTitle: string) {
|
||||||
// Expect an error in the shape provided by Angular's $http service.
|
// Expect an error in the shape provided by http service.
|
||||||
if (error && error.data) {
|
if (error && error.body) {
|
||||||
const { error: errorString, statusCode, message } = error.data;
|
const { error: errorString, statusCode, message } = error.body;
|
||||||
return {
|
return {
|
||||||
title: errorTitle,
|
title: errorTitle,
|
||||||
text: `${statusCode}: ${errorString}. ${message}`,
|
text: `${statusCode}: ${errorString}. ${message}`,
|
||||||
|
@ -17,26 +17,26 @@ function createToastConfig(error, errorTitle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showApiWarning(error, errorTitle) {
|
export function showApiWarning(error: any, errorTitle: string) {
|
||||||
const toastConfig = createToastConfig(error, errorTitle);
|
const toastConfig = createToastConfig(error, errorTitle);
|
||||||
|
|
||||||
if (toastConfig) {
|
if (toastConfig) {
|
||||||
return toastNotifications.addWarning(toastConfig);
|
return getNotifications().toasts.addWarning(toastConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
||||||
// unexpected happened.
|
// unexpected happened.
|
||||||
return fatalError(error, errorTitle);
|
return getFatalErrors().add(error, errorTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showApiError(error, errorTitle) {
|
export function showApiError(error: any, errorTitle: string) {
|
||||||
const toastConfig = createToastConfig(error, errorTitle);
|
const toastConfig = createToastConfig(error, errorTitle);
|
||||||
|
|
||||||
if (toastConfig) {
|
if (toastConfig) {
|
||||||
return toastNotifications.addDanger(toastConfig);
|
return getNotifications().toasts.addDanger(toastConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
||||||
// unexpected happened.
|
// unexpected happened.
|
||||||
fatalError(error, errorTitle);
|
getFatalErrors().add(error, errorTitle);
|
||||||
}
|
}
|
|
@ -4,16 +4,21 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links';
|
let esBase = '';
|
||||||
|
let xPackBase = '';
|
||||||
|
|
||||||
const esBase = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}`;
|
export function setEsBaseAndXPackBase(elasticWebsiteUrl, docLinksVersion) {
|
||||||
const xPackBase = `${ELASTIC_WEBSITE_URL}guide/en/x-pack/${DOC_LINK_VERSION}`;
|
esBase = `${elasticWebsiteUrl}guide/en/elasticsearch/reference/${docLinksVersion}`;
|
||||||
|
xPackBase = `${elasticWebsiteUrl}guide/en/x-pack/${docLinksVersion}`;
|
||||||
|
}
|
||||||
|
|
||||||
export const logisticalDetailsUrl = `${esBase}/rollup-job-config.html#_logistical_details`;
|
export const getLogisticalDetailsUrl = () => `${esBase}/rollup-job-config.html#_logistical_details`;
|
||||||
export const dateHistogramDetailsUrl = `${esBase}/rollup-job-config.html#_date_histogram_2`;
|
export const getDateHistogramDetailsUrl = () =>
|
||||||
export const termsDetailsUrl = `${esBase}/rollup-job-config.html#_terms_2`;
|
`${esBase}/rollup-job-config.html#_date_histogram_2`;
|
||||||
export const histogramDetailsUrl = `${esBase}/rollup-job-config.html#_histogram_2`;
|
export const getTermsDetailsUrl = () => `${esBase}/rollup-job-config.html#_terms_2`;
|
||||||
export const metricsDetailsUrl = `${esBase}/rollup-job-config.html#rollup-metrics-config`;
|
export const getHistogramDetailsUrl = () => `${esBase}/rollup-job-config.html#_histogram_2`;
|
||||||
|
export const getMetricsDetailsUrl = () => `${esBase}/rollup-job-config.html#rollup-metrics-config`;
|
||||||
|
|
||||||
export const dateHistogramAggregationUrl = `${esBase}/search-aggregations-bucket-datehistogram-aggregation.html`;
|
export const getDateHistogramAggregationUrl = () =>
|
||||||
export const cronUrl = `${xPackBase}/trigger-schedule.html#_cron_expressions`;
|
`${esBase}/search-aggregations-bucket-datehistogram-aggregation.html`;
|
||||||
|
export const getCronUrl = () => `${xPackBase}/trigger-schedule.html#_cron_expressions`;
|
||||||
|
|
|
@ -4,14 +4,17 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This is an Angular service, which is why we use this provider pattern to access it within
|
import { HttpStart } from 'src/core/public';
|
||||||
// our React app.
|
|
||||||
let _http;
|
|
||||||
|
|
||||||
export function setHttp(http) {
|
let _http: HttpStart | null = null;
|
||||||
|
|
||||||
|
export function setHttp(http: HttpStart) {
|
||||||
_http = http;
|
_http = http;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getHttp() {
|
export function getHttp() {
|
||||||
|
if (!_http) {
|
||||||
|
throw new Error('Rollup http is not defined');
|
||||||
|
}
|
||||||
return _http;
|
return _http;
|
||||||
}
|
}
|
|
@ -11,13 +11,14 @@ export { showApiError, showApiWarning } from './api_errors';
|
||||||
export { listBreadcrumb, createBreadcrumb } from './breadcrumbs';
|
export { listBreadcrumb, createBreadcrumb } from './breadcrumbs';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
logisticalDetailsUrl,
|
setEsBaseAndXPackBase,
|
||||||
dateHistogramDetailsUrl,
|
getLogisticalDetailsUrl,
|
||||||
dateHistogramAggregationUrl,
|
getDateHistogramDetailsUrl,
|
||||||
termsDetailsUrl,
|
getDateHistogramAggregationUrl,
|
||||||
histogramDetailsUrl,
|
getTermsDetailsUrl,
|
||||||
metricsDetailsUrl,
|
getHistogramDetailsUrl,
|
||||||
cronUrl,
|
getMetricsDetailsUrl,
|
||||||
|
getCronUrl,
|
||||||
} from './documentation_links';
|
} from './documentation_links';
|
||||||
|
|
||||||
export { filterItems } from './filter_items';
|
export { filterItems } from './filter_items';
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { fatalError } from 'ui/notify';
|
|
||||||
|
|
||||||
import { CRUD_APP_BASE_PATH } from '../../constants';
|
import { CRUD_APP_BASE_PATH } from '../../constants';
|
||||||
import {
|
import {
|
||||||
|
@ -24,6 +23,8 @@ import {
|
||||||
CLEAR_CREATE_JOB_ERRORS,
|
CLEAR_CREATE_JOB_ERRORS,
|
||||||
} from '../action_types';
|
} from '../action_types';
|
||||||
|
|
||||||
|
import { getFatalErrors } from '../../../kibana_services';
|
||||||
|
|
||||||
export const createJob = jobConfig => async dispatch => {
|
export const createJob = jobConfig => async dispatch => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: CREATE_JOB_START,
|
type: CREATE_JOB_START,
|
||||||
|
@ -39,12 +40,13 @@ export const createJob = jobConfig => async dispatch => {
|
||||||
]);
|
]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
const { statusCode, data } = error;
|
const { body } = error;
|
||||||
|
const statusCode = error.statusCode || (body && body.statusCode);
|
||||||
|
|
||||||
// Expect an error in the shape provided by Angular's $http service.
|
// Expect an error in the shape provided by http service.
|
||||||
if (data) {
|
if (body) {
|
||||||
// Some errors have statusCode directly available but some are under a data property.
|
// Some errors have statusCode directly available but some are under a data property.
|
||||||
if ((statusCode || (data && data.statusCode)) === 409) {
|
if (statusCode === 409) {
|
||||||
return dispatch({
|
return dispatch({
|
||||||
type: CREATE_JOB_FAILURE,
|
type: CREATE_JOB_FAILURE,
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -67,9 +69,9 @@ export const createJob = jobConfig => async dispatch => {
|
||||||
error: {
|
error: {
|
||||||
message: i18n.translate('xpack.rollupJobs.createAction.failedDefaultErrorMessage', {
|
message: i18n.translate('xpack.rollupJobs.createAction.failedDefaultErrorMessage', {
|
||||||
defaultMessage: 'Request failed with a {statusCode} error. {message}',
|
defaultMessage: 'Request failed with a {statusCode} error. {message}',
|
||||||
values: { statusCode, message: data.message },
|
values: { statusCode, message: body.message },
|
||||||
}),
|
}),
|
||||||
cause: data.cause,
|
cause: body.cause,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -78,7 +80,7 @@ export const createJob = jobConfig => async dispatch => {
|
||||||
|
|
||||||
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
// This error isn't an HTTP error, so let the fatal error screen tell the user something
|
||||||
// unexpected happened.
|
// unexpected happened.
|
||||||
return fatalError(
|
return getFatalErrors().add(
|
||||||
error,
|
error,
|
||||||
i18n.translate('xpack.rollupJobs.createAction.errorTitle', {
|
i18n.translate('xpack.rollupJobs.createAction.errorTitle', {
|
||||||
defaultMessage: 'Error creating rollup job',
|
defaultMessage: 'Error creating rollup job',
|
||||||
|
@ -86,7 +88,7 @@ export const createJob = jobConfig => async dispatch => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const deserializedJob = deserializeJob(newJob.data);
|
const deserializedJob = deserializeJob(newJob);
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: CREATE_JOB_SUCCESS,
|
type: CREATE_JOB_SUCCESS,
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { toastNotifications } from 'ui/notify';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
deleteJobs as sendDeleteJobsRequest,
|
deleteJobs as sendDeleteJobsRequest,
|
||||||
|
@ -19,6 +18,8 @@ import { UPDATE_JOB_START, UPDATE_JOB_SUCCESS, UPDATE_JOB_FAILURE } from '../act
|
||||||
import { refreshJobs } from './refresh_jobs';
|
import { refreshJobs } from './refresh_jobs';
|
||||||
import { closeDetailPanel } from './detail_panel';
|
import { closeDetailPanel } from './detail_panel';
|
||||||
|
|
||||||
|
import { getNotifications } from '../../../kibana_services';
|
||||||
|
|
||||||
export const deleteJobs = jobIds => async (dispatch, getState) => {
|
export const deleteJobs = jobIds => async (dispatch, getState) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: UPDATE_JOB_START,
|
type: UPDATE_JOB_START,
|
||||||
|
@ -40,14 +41,14 @@ export const deleteJobs = jobIds => async (dispatch, getState) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jobIds.length === 1) {
|
if (jobIds.length === 1) {
|
||||||
toastNotifications.addSuccess(
|
getNotifications().toasts.addSuccess(
|
||||||
i18n.translate('xpack.rollupJobs.deleteAction.successSingleNotificationTitle', {
|
i18n.translate('xpack.rollupJobs.deleteAction.successSingleNotificationTitle', {
|
||||||
defaultMessage: `Rollup job '{jobId}' was deleted`,
|
defaultMessage: `Rollup job '{jobId}' was deleted`,
|
||||||
values: { jobId: jobIds[0] },
|
values: { jobId: jobIds[0] },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
toastNotifications.addSuccess(
|
getNotifications().toasts.addSuccess(
|
||||||
i18n.translate('xpack.rollupJobs.deleteAction.successMultipleNotificationTitle', {
|
i18n.translate('xpack.rollupJobs.deleteAction.successMultipleNotificationTitle', {
|
||||||
defaultMessage: '{count} rollup jobs were deleted',
|
defaultMessage: '{count} rollup jobs were deleted',
|
||||||
values: { count: jobIds.length },
|
values: { count: jobIds.length },
|
||||||
|
|
|
@ -4,15 +4,11 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import {
|
|
||||||
addToggleExtension,
|
|
||||||
addBadgeExtension,
|
|
||||||
} from '../../../index_management/public/index_management_extensions';
|
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
|
|
||||||
const propertyPath = 'isRollupIndex';
|
const propertyPath = 'isRollupIndex';
|
||||||
export const rollupToggleExtension = {
|
export const rollupToggleExtension = {
|
||||||
matchIndex: index => {
|
matchIndex: (index: { isRollupIndex: boolean }) => {
|
||||||
return get(index, propertyPath);
|
return get(index, propertyPath);
|
||||||
},
|
},
|
||||||
label: i18n.translate('xpack.rollupJobs.indexMgmtToggle.toggleLabel', {
|
label: i18n.translate('xpack.rollupJobs.indexMgmtToggle.toggleLabel', {
|
||||||
|
@ -20,8 +16,9 @@ export const rollupToggleExtension = {
|
||||||
}),
|
}),
|
||||||
name: 'rollupToggle',
|
name: 'rollupToggle',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const rollupBadgeExtension = {
|
export const rollupBadgeExtension = {
|
||||||
matchIndex: index => {
|
matchIndex: (index: { isRollupIndex: boolean }) => {
|
||||||
return get(index, propertyPath);
|
return get(index, propertyPath);
|
||||||
},
|
},
|
||||||
label: i18n.translate('xpack.rollupJobs.indexMgmtBadge.rollupLabel', {
|
label: i18n.translate('xpack.rollupJobs.indexMgmtBadge.rollupLabel', {
|
||||||
|
@ -30,6 +27,3 @@ export const rollupBadgeExtension = {
|
||||||
color: 'secondary',
|
color: 'secondary',
|
||||||
filterExpression: 'isRollupIndex:true',
|
filterExpression: 'isRollupIndex:true',
|
||||||
};
|
};
|
||||||
|
|
||||||
addBadgeExtension(rollupBadgeExtension);
|
|
||||||
addToggleExtension(rollupToggleExtension);
|
|
|
@ -1,17 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import chrome from 'ui/chrome';
|
|
||||||
|
|
||||||
import { initIndexPatternCreation } from './register';
|
|
||||||
import { CONFIG_ROLLUPS } from '../../common';
|
|
||||||
|
|
||||||
const uiSettings = chrome.getUiSettingsClient();
|
|
||||||
const isRollupIndexPatternsEnabled = uiSettings.get(CONFIG_ROLLUPS);
|
|
||||||
|
|
||||||
if (isRollupIndexPatternsEnabled) {
|
|
||||||
initIndexPatternCreation();
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { setup as managementSetup } from '../../../../../../src/legacy/core_plugins/management/public/legacy';
|
|
||||||
import { RollupIndexPatternCreationConfig } from './rollup_index_pattern_creation_config';
|
|
||||||
|
|
||||||
export function initIndexPatternCreation() {
|
|
||||||
managementSetup.indexPattern.creation.add(RollupIndexPatternCreationConfig);
|
|
||||||
}
|
|
|
@ -6,10 +6,8 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { npSetup } from 'ui/new_platform';
|
|
||||||
|
|
||||||
import { RollupPrompt } from './components/rollup_prompt';
|
import { RollupPrompt } from './components/rollup_prompt';
|
||||||
import { setHttpClient, getRollupIndices } from '../services/api';
|
|
||||||
import { IndexPatternCreationConfig } from '../../../../../../src/legacy/core_plugins/management/public';
|
import { IndexPatternCreationConfig } from '../../../../../../src/legacy/core_plugins/management/public';
|
||||||
|
|
||||||
const rollupIndexPatternTypeName = i18n.translate(
|
const rollupIndexPatternTypeName = i18n.translate(
|
||||||
|
@ -54,7 +52,6 @@ export class RollupIndexPatternCreationConfig extends IndexPatternCreationConfig
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
setHttpClient(this.httpClient);
|
|
||||||
this.rollupIndex = null;
|
this.rollupIndex = null;
|
||||||
this.rollupJobs = [];
|
this.rollupJobs = [];
|
||||||
this.rollupIndicesCapabilities = {};
|
this.rollupIndicesCapabilities = {};
|
||||||
|
@ -67,9 +64,10 @@ export class RollupIndexPatternCreationConfig extends IndexPatternCreationConfig
|
||||||
// This is a hack intended to prevent the getRollupIndices() request from being sent if
|
// This is a hack intended to prevent the getRollupIndices() request from being sent if
|
||||||
// we're on /logout. There is a race condition that can arise on that page, whereby this
|
// we're on /logout. There is a race condition that can arise on that page, whereby this
|
||||||
// request resolves after the logout request resolves, and un-clears the session ID.
|
// request resolves after the logout request resolves, and un-clears the session ID.
|
||||||
const isAnonymous = npSetup.core.http.anonymousPaths.isAnonymous(window.location.pathname);
|
const isAnonymous = this.httpClient.anonymousPaths.isAnonymous(window.location.pathname);
|
||||||
if (!isAnonymous) {
|
if (!isAnonymous) {
|
||||||
this.rollupIndicesCapabilities = await getRollupIndices();
|
const response = await this.httpClient.get('/api/rollup/indices');
|
||||||
|
this.rollupIndicesCapabilities = response || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rollupIndices = Object.keys(this.rollupIndicesCapabilities);
|
this.rollupIndices = Object.keys(this.rollupIndicesCapabilities);
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import chrome from 'ui/chrome';
|
|
||||||
import { initIndexPatternList } from './register';
|
|
||||||
import { CONFIG_ROLLUPS } from '../../common';
|
|
||||||
|
|
||||||
const uiSettings = chrome.getUiSettingsClient();
|
|
||||||
const isRollupIndexPatternsEnabled = uiSettings.get(CONFIG_ROLLUPS);
|
|
||||||
|
|
||||||
if (isRollupIndexPatternsEnabled) {
|
|
||||||
initIndexPatternList();
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { setup as managementSetup } from '../../../../../../src/legacy/core_plugins/management/public/legacy';
|
|
||||||
import { RollupIndexPatternListConfig } from './rollup_index_pattern_list_config';
|
|
||||||
|
|
||||||
export function initIndexPatternList() {
|
|
||||||
managementSetup.indexPattern.list.add(RollupIndexPatternListConfig);
|
|
||||||
}
|
|
30
x-pack/legacy/plugins/rollup/public/kibana_services.ts
Normal file
30
x-pack/legacy/plugins/rollup/public/kibana_services.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NotificationsStart, FatalErrorsSetup } from 'src/core/public';
|
||||||
|
|
||||||
|
let notifications: NotificationsStart | null = null;
|
||||||
|
let fatalErrors: FatalErrorsSetup | null = null;
|
||||||
|
|
||||||
|
export function getNotifications() {
|
||||||
|
if (!notifications) {
|
||||||
|
throw new Error('Rollup notifications is not defined');
|
||||||
|
}
|
||||||
|
return notifications;
|
||||||
|
}
|
||||||
|
export function setNotifications(newNotifications: NotificationsStart) {
|
||||||
|
notifications = newNotifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFatalErrors() {
|
||||||
|
if (!fatalErrors) {
|
||||||
|
throw new Error('Rollup fatalErrors is not defined');
|
||||||
|
}
|
||||||
|
return fatalErrors;
|
||||||
|
}
|
||||||
|
export function setFatalErrors(newFatalErrors: FatalErrorsSetup) {
|
||||||
|
fatalErrors = newFatalErrors;
|
||||||
|
}
|
30
x-pack/legacy/plugins/rollup/public/legacy.ts
Normal file
30
x-pack/legacy/plugins/rollup/public/legacy.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { npSetup, npStart } from 'ui/new_platform';
|
||||||
|
import { editorConfigProviders } from 'ui/vis/config';
|
||||||
|
import { aggTypeFilters } from 'ui/agg_types/filter';
|
||||||
|
import { aggTypeFieldFilters } from 'ui/agg_types/param_types/filter';
|
||||||
|
import { addSearchStrategy } from '../../../../../src/plugins/data/public';
|
||||||
|
import { RollupPlugin } from './plugin';
|
||||||
|
import { setup as management } from '../../../../../src/legacy/core_plugins/management/public/legacy';
|
||||||
|
import { addBadgeExtension, addToggleExtension } from '../../index_management/public';
|
||||||
|
|
||||||
|
const plugin = new RollupPlugin();
|
||||||
|
|
||||||
|
export const setup = plugin.setup(npSetup.core, {
|
||||||
|
...npSetup.plugins,
|
||||||
|
__LEGACY: {
|
||||||
|
aggTypeFilters,
|
||||||
|
aggTypeFieldFilters,
|
||||||
|
editorConfigProviders,
|
||||||
|
addSearchStrategy,
|
||||||
|
addBadgeExtension,
|
||||||
|
addToggleExtension,
|
||||||
|
managementLegacy: management,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const start = plugin.start(npStart.core);
|
12
x-pack/legacy/plugins/rollup/public/legacy_imports.ts
Normal file
12
x-pack/legacy/plugins/rollup/public/legacy_imports.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export { findIllegalCharactersInIndexName, INDEX_ILLEGAL_CHARACTERS_VISIBLE } from 'ui/indices';
|
||||||
|
|
||||||
|
export { AggTypeFilters } from 'ui/agg_types/filter';
|
||||||
|
export { AggTypeFieldFilters } from 'ui/agg_types/param_types/filter';
|
||||||
|
export { EditorConfigProviderRegistry } from 'ui/vis/config';
|
128
x-pack/legacy/plugins/rollup/public/plugin.ts
Normal file
128
x-pack/legacy/plugins/rollup/public/plugin.ts
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { CoreSetup, CoreStart, Plugin } from 'kibana/public';
|
||||||
|
import {
|
||||||
|
EditorConfigProviderRegistry,
|
||||||
|
AggTypeFilters,
|
||||||
|
AggTypeFieldFilters,
|
||||||
|
} from './legacy_imports';
|
||||||
|
import { SearchStrategyProvider } from '../../../../../src/plugins/data/public';
|
||||||
|
import { ManagementSetup as ManagementSetupLegacy } from '../../../../../src/legacy/core_plugins/management/public/np_ready';
|
||||||
|
import { rollupBadgeExtension, rollupToggleExtension } from './extend_index_management';
|
||||||
|
// @ts-ignore
|
||||||
|
import { RollupIndexPatternCreationConfig } from './index_pattern_creation/rollup_index_pattern_creation_config';
|
||||||
|
// @ts-ignore
|
||||||
|
import { RollupIndexPatternListConfig } from './index_pattern_list/rollup_index_pattern_list_config';
|
||||||
|
import { getRollupSearchStrategy } from './search/rollup_search_strategy';
|
||||||
|
// @ts-ignore
|
||||||
|
import { initAggTypeFilter } from './visualize/agg_type_filter';
|
||||||
|
// @ts-ignore
|
||||||
|
import { initAggTypeFieldFilter } from './visualize/agg_type_field_filter';
|
||||||
|
// @ts-ignore
|
||||||
|
import { initEditorConfig } from './visualize/editor_config';
|
||||||
|
import { CONFIG_ROLLUPS } from '../common';
|
||||||
|
import {
|
||||||
|
FeatureCatalogueCategory,
|
||||||
|
HomePublicPluginSetup,
|
||||||
|
} from '../../../../../src/plugins/home/public';
|
||||||
|
// @ts-ignore
|
||||||
|
import { CRUD_APP_BASE_PATH } from './crud_app/constants';
|
||||||
|
import { ManagementSetup } from '../../../../../src/plugins/management/public';
|
||||||
|
// @ts-ignore
|
||||||
|
import { setEsBaseAndXPackBase, setHttp } from './crud_app/services';
|
||||||
|
import { setNotifications, setFatalErrors } from './kibana_services';
|
||||||
|
import { renderApp } from './application';
|
||||||
|
|
||||||
|
export interface RollupPluginSetupDependencies {
|
||||||
|
__LEGACY: {
|
||||||
|
aggTypeFilters: AggTypeFilters;
|
||||||
|
aggTypeFieldFilters: AggTypeFieldFilters;
|
||||||
|
editorConfigProviders: EditorConfigProviderRegistry;
|
||||||
|
addSearchStrategy: (searchStrategy: SearchStrategyProvider) => void;
|
||||||
|
managementLegacy: ManagementSetupLegacy;
|
||||||
|
addBadgeExtension: (badgeExtension: any) => void;
|
||||||
|
addToggleExtension: (toggleExtension: any) => void;
|
||||||
|
};
|
||||||
|
home?: HomePublicPluginSetup;
|
||||||
|
management: ManagementSetup;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RollupPlugin implements Plugin {
|
||||||
|
setup(
|
||||||
|
core: CoreSetup,
|
||||||
|
{
|
||||||
|
__LEGACY: {
|
||||||
|
aggTypeFilters,
|
||||||
|
aggTypeFieldFilters,
|
||||||
|
editorConfigProviders,
|
||||||
|
addSearchStrategy,
|
||||||
|
managementLegacy,
|
||||||
|
addBadgeExtension,
|
||||||
|
addToggleExtension,
|
||||||
|
},
|
||||||
|
home,
|
||||||
|
management,
|
||||||
|
}: RollupPluginSetupDependencies
|
||||||
|
) {
|
||||||
|
setFatalErrors(core.fatalErrors);
|
||||||
|
addBadgeExtension(rollupBadgeExtension);
|
||||||
|
addToggleExtension(rollupToggleExtension);
|
||||||
|
|
||||||
|
const isRollupIndexPatternsEnabled = core.uiSettings.get(CONFIG_ROLLUPS);
|
||||||
|
|
||||||
|
if (isRollupIndexPatternsEnabled) {
|
||||||
|
managementLegacy.indexPattern.creation.add(RollupIndexPatternCreationConfig);
|
||||||
|
managementLegacy.indexPattern.list.add(RollupIndexPatternListConfig);
|
||||||
|
addSearchStrategy(getRollupSearchStrategy(core.http.fetch));
|
||||||
|
initAggTypeFilter(aggTypeFilters);
|
||||||
|
initAggTypeFieldFilter(aggTypeFieldFilters);
|
||||||
|
initEditorConfig(editorConfigProviders);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (home) {
|
||||||
|
home.featureCatalogue.register({
|
||||||
|
id: 'rollup_jobs',
|
||||||
|
title: 'Rollups',
|
||||||
|
description: i18n.translate('xpack.rollupJobs.featureCatalogueDescription', {
|
||||||
|
defaultMessage:
|
||||||
|
'Summarize and store historical data in a smaller index for future analysis.',
|
||||||
|
}),
|
||||||
|
icon: 'indexRollupApp',
|
||||||
|
path: `#${CRUD_APP_BASE_PATH}/job_list`,
|
||||||
|
showOnHomePage: true,
|
||||||
|
category: FeatureCatalogueCategory.ADMIN,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const esSection = management.sections.getSection('elasticsearch');
|
||||||
|
if (esSection) {
|
||||||
|
esSection.registerApp({
|
||||||
|
id: 'rollup_jobs',
|
||||||
|
title: i18n.translate('xpack.rollupJobs.appTitle', { defaultMessage: 'Rollup Jobs' }),
|
||||||
|
order: 3,
|
||||||
|
mount(params) {
|
||||||
|
params.setBreadcrumbs([
|
||||||
|
{
|
||||||
|
text: i18n.translate('xpack.rollupJobs.breadcrumbsTitle', {
|
||||||
|
defaultMessage: 'Rollup Jobs',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
return renderApp(core, params);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start(core: CoreStart) {
|
||||||
|
setHttp(core.http);
|
||||||
|
setNotifications(core.notifications);
|
||||||
|
setEsBaseAndXPackBase(core.docLinks.ELASTIC_WEBSITE_URL, core.docLinks.DOC_LINK_VERSION);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import chrome from 'ui/chrome';
|
|
||||||
|
|
||||||
import { initSearch } from './register';
|
|
||||||
import { CONFIG_ROLLUPS } from '../../common';
|
|
||||||
|
|
||||||
const uiSettings = chrome.getUiSettingsClient();
|
|
||||||
const isRollupIndexPatternsEnabled = uiSettings.get(CONFIG_ROLLUPS);
|
|
||||||
|
|
||||||
if (isRollupIndexPatternsEnabled) {
|
|
||||||
initSearch();
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { addSearchStrategy } from '../../../../../../src/plugins/data/public';
|
|
||||||
import { rollupSearchStrategy } from './rollup_search_strategy';
|
|
||||||
|
|
||||||
export function initSearch() {
|
|
||||||
addSearchStrategy(rollupSearchStrategy);
|
|
||||||
}
|
|
|
@ -4,10 +4,17 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { kfetch } from 'ui/kfetch';
|
import { HttpSetup } from 'src/core/public';
|
||||||
import { SearchError, getSearchErrorType } from '../../../../../../src/plugins/data/public';
|
import {
|
||||||
|
SearchError,
|
||||||
|
getSearchErrorType,
|
||||||
|
IIndexPattern,
|
||||||
|
SearchStrategyProvider,
|
||||||
|
SearchResponse,
|
||||||
|
SearchRequest,
|
||||||
|
} from '../../../../../../src/plugins/data/public';
|
||||||
|
|
||||||
function serializeFetchParams(searchRequests) {
|
function serializeFetchParams(searchRequests: SearchRequest[]) {
|
||||||
return JSON.stringify(
|
return JSON.stringify(
|
||||||
searchRequests.map(searchRequestWithFetchParams => {
|
searchRequests.map(searchRequestWithFetchParams => {
|
||||||
const indexPattern =
|
const indexPattern =
|
||||||
|
@ -17,7 +24,7 @@ function serializeFetchParams(searchRequests) {
|
||||||
} = searchRequestWithFetchParams;
|
} = searchRequestWithFetchParams;
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
size: size,
|
size,
|
||||||
aggregations: aggs,
|
aggregations: aggs,
|
||||||
query: _query,
|
query: _query,
|
||||||
};
|
};
|
||||||
|
@ -30,7 +37,7 @@ function serializeFetchParams(searchRequests) {
|
||||||
// Rollup search always returns 0 hits, but visualizations expect search responses
|
// Rollup search always returns 0 hits, but visualizations expect search responses
|
||||||
// to return hits > 0, otherwise they do not render. We fake the number of hits here
|
// to return hits > 0, otherwise they do not render. We fake the number of hits here
|
||||||
// by counting the number of aggregation buckets/values returned by rollup search.
|
// by counting the number of aggregation buckets/values returned by rollup search.
|
||||||
function shimHitsInFetchResponse(response) {
|
function shimHitsInFetchResponse(response: SearchResponse[]) {
|
||||||
return response.map(result => {
|
return response.map(result => {
|
||||||
const buckets = result.aggregations
|
const buckets = result.aggregations
|
||||||
? Object.keys(result.aggregations).reduce((allBuckets, agg) => {
|
? Object.keys(result.aggregations).reduce((allBuckets, agg) => {
|
||||||
|
@ -51,17 +58,16 @@ function shimHitsInFetchResponse(response) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const rollupSearchStrategy = {
|
export const getRollupSearchStrategy = (fetch: HttpSetup['fetch']): SearchStrategyProvider => ({
|
||||||
id: 'rollup',
|
id: 'rollup',
|
||||||
|
|
||||||
search: ({ searchRequests, Promise }) => {
|
search: ({ searchRequests }) => {
|
||||||
// Serialize the fetch params into a format suitable for the body of an ES query.
|
// Serialize the fetch params into a format suitable for the body of an ES query.
|
||||||
const serializedFetchParams = serializeFetchParams(searchRequests);
|
const serializedFetchParams = serializeFetchParams(searchRequests);
|
||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const promise = kfetch({
|
const promise = fetch('../api/rollup/search', {
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
pathname: '../api/rollup/search',
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: serializedFetchParams,
|
body: serializedFetchParams,
|
||||||
});
|
});
|
||||||
|
@ -69,17 +75,17 @@ export const rollupSearchStrategy = {
|
||||||
return {
|
return {
|
||||||
searching: promise.then(shimHitsInFetchResponse).catch(error => {
|
searching: promise.then(shimHitsInFetchResponse).catch(error => {
|
||||||
const {
|
const {
|
||||||
body: { statusText, error: title, message },
|
body: { statusCode, error: title, message },
|
||||||
res: { url },
|
res: { url },
|
||||||
} = error;
|
} = error;
|
||||||
|
|
||||||
// Format kfetch error as a SearchError.
|
// Format fetch error as a SearchError.
|
||||||
const searchError = new SearchError({
|
const searchError = new SearchError({
|
||||||
status: statusText,
|
status: statusCode,
|
||||||
title,
|
title,
|
||||||
message: `Rollup search error: ${message}`,
|
message: `Rollup search error: ${message}`,
|
||||||
path: url,
|
path: url,
|
||||||
type: getSearchErrorType({ message }),
|
type: getSearchErrorType({ message }) || '',
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.reject(searchError);
|
return Promise.reject(searchError);
|
||||||
|
@ -88,11 +94,11 @@ export const rollupSearchStrategy = {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
isViable: indexPattern => {
|
isViable: (indexPattern: IIndexPattern) => {
|
||||||
if (!indexPattern) {
|
if (!indexPattern) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return indexPattern.type === 'rollup';
|
return indexPattern.type === 'rollup';
|
||||||
},
|
},
|
||||||
};
|
});
|
|
@ -1,14 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
let httpClient;
|
|
||||||
export const setHttpClient = client => {
|
|
||||||
httpClient = client;
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function getRollupIndices() {
|
|
||||||
const response = await httpClient.get('/api/rollup/indices');
|
|
||||||
return response || {};
|
|
||||||
}
|
|
|
@ -4,9 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { aggTypeFieldFilters } from 'ui/agg_types/param_types/filter';
|
export function initAggTypeFieldFilter(aggTypeFieldFilters) {
|
||||||
|
|
||||||
export function initAggTypeFieldFilter() {
|
|
||||||
/**
|
/**
|
||||||
* If rollup index pattern, check its capabilities
|
* If rollup index pattern, check its capabilities
|
||||||
* and limit available fields for a given aggType based on that.
|
* and limit available fields for a given aggType based on that.
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { aggTypeFilters } from 'ui/agg_types/filter';
|
export function initAggTypeFilter(aggTypeFilters) {
|
||||||
|
|
||||||
export function initAggTypeFilter() {
|
|
||||||
/**
|
/**
|
||||||
* If rollup index pattern, check its capabilities
|
* If rollup index pattern, check its capabilities
|
||||||
* and limit available aggregations based on that.
|
* and limit available aggregations based on that.
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { editorConfigProviders } from 'ui/vis/config';
|
|
||||||
|
|
||||||
export function initEditorConfig() {
|
export function initEditorConfig(editorConfigProviders) {
|
||||||
// Limit agg params based on rollup capabilities
|
// Limit agg params based on rollup capabilities
|
||||||
editorConfigProviders.register((indexPattern, aggConfig) => {
|
editorConfigProviders.register((indexPattern, aggConfig) => {
|
||||||
if (indexPattern.type !== 'rollup') {
|
if (indexPattern.type !== 'rollup') {
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import chrome from 'ui/chrome';
|
|
||||||
|
|
||||||
import { initAggTypeFilter } from './agg_type_filter';
|
|
||||||
import { initAggTypeFieldFilter } from './agg_type_field_filter';
|
|
||||||
import { initEditorConfig } from './editor_config';
|
|
||||||
import { CONFIG_ROLLUPS } from '../../common';
|
|
||||||
|
|
||||||
const uiSettings = chrome.getUiSettingsClient();
|
|
||||||
const isRollupIndexPatternsEnabled = uiSettings.get(CONFIG_ROLLUPS);
|
|
||||||
|
|
||||||
if (isRollupIndexPatternsEnabled) {
|
|
||||||
initAggTypeFilter();
|
|
||||||
initAggTypeFieldFilter();
|
|
||||||
initEditorConfig();
|
|
||||||
}
|
|
Loading…
Reference in a new issue