From e60a5b0e852d4bdff23d08cbfa77cfcb570ccd1c Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Mon, 21 Oct 2019 01:37:55 -0700
Subject: [PATCH 001/191] [ML] Transforms: Fix page layout (#48628)
Fixes the overall page layout of the transform plugin to be in line with the rest of the Kibana Elasticsearch management section.
---
.../transform/public/app/constants/index.ts | 1 +
.../plugins/transform/public/app/index.scss | 1 +
.../step_define/step_define_form.tsx | 2 +-
.../components/wizard/_index.scss | 1 +
.../components/wizard/_wizard.scss | 5 ++
.../components/wizard/wizard.tsx | 2 +-
.../create_transform_section.tsx | 41 ++++++---
.../create_transform_button.test.tsx.snap | 3 +-
.../create_transform_button.tsx | 3 +-
.../refresh_transform_list_button.tsx | 10 ++-
.../transform_list/transform_list.tsx | 20 +++++
.../transform_management_section.tsx | 84 ++++++++++---------
.../documentation/documentation_links.ts | 10 +--
.../legacy/plugins/transform/public/plugin.ts | 2 +-
14 files changed, 116 insertions(+), 69 deletions(-)
create mode 100644 x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_index.scss
create mode 100644 x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_wizard.scss
diff --git a/x-pack/legacy/plugins/transform/public/app/constants/index.ts b/x-pack/legacy/plugins/transform/public/app/constants/index.ts
index 4988ea660b418..85ffc222f59a2 100644
--- a/x-pack/legacy/plugins/transform/public/app/constants/index.ts
+++ b/x-pack/legacy/plugins/transform/public/app/constants/index.ts
@@ -14,6 +14,7 @@ export enum SECTION_SLUG {
export enum TRANSFORM_DOC_PATHS {
default = 'docs.html',
plugins = 'plugins.html',
+ transforms = 'transforms.html',
}
// UI Metric constants
diff --git a/x-pack/legacy/plugins/transform/public/app/index.scss b/x-pack/legacy/plugins/transform/public/app/index.scss
index 28459d06b5cb1..836929174875e 100644
--- a/x-pack/legacy/plugins/transform/public/app/index.scss
+++ b/x-pack/legacy/plugins/transform/public/app/index.scss
@@ -12,6 +12,7 @@
@import 'sections/create_transform/components/aggregation_list/index';
@import 'sections/create_transform/components/group_by_list/index';
+@import 'sections/create_transform/components/wizard/index';
@import 'sections/transform_management/components/create_transform_button/index';
@import 'sections/transform_management/components/stats_bar/index';
@import 'sections/transform_management/components/transform_list/index';
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx
index 2e7cf9911555e..49017ac9e3c02 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx
@@ -827,7 +827,7 @@ export const StepDefineForm: SFC = React.memo(({ overrides = {}, onChange
-
+
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_index.scss b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_index.scss
new file mode 100644
index 0000000000000..957f378640ea6
--- /dev/null
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_index.scss
@@ -0,0 +1 @@
+@import './wizard';
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_wizard.scss b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_wizard.scss
new file mode 100644
index 0000000000000..5a3b03f56a141
--- /dev/null
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/_wizard.scss
@@ -0,0 +1,5 @@
+.transform__steps {
+ .euiStep__content {
+ padding-right: 0px;
+ }
+}
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx
index 0ed40f2d6166b..490fd150e1bc1 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/wizard/wizard.tsx
@@ -173,5 +173,5 @@ export const Wizard: SFC = React.memo(() => {
},
];
- return ;
+ return ;
});
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx
index 8e33b2ebac89a..2214d1f5adfff 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/create_transform_section.tsx
@@ -12,17 +12,19 @@ import { i18n } from '@kbn/i18n';
import {
EuiBetaBadge,
- EuiPage,
+ EuiButtonEmpty,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPageContent,
EuiPageBody,
EuiPageContentBody,
- EuiPageContentHeader,
- EuiPageContentHeaderSection,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';
import { APP_CREATE_TRANSFORM_CLUSTER_PRIVILEGES } from '../../../../common/constants';
import { breadcrumbService, docTitleService, BREADCRUMB_SECTION } from '../../services/navigation';
+import { documentationLinksService } from '../../services/documentation';
import { PrivilegesWrapper } from '../../lib/authorization';
import { KibanaProvider } from '../../lib/kibana';
@@ -39,11 +41,11 @@ export const CreateTransformSection: FC = ({ match }) => {
return (
-
-
-
-
-
+
+
+
+
+
= ({ match }) => {
)}
/>
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
);
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap
index 94841ad026f80..d85f9379159d0 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap
+++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/__snapshots__/create_transform_button.test.tsx.snap
@@ -12,10 +12,9 @@ exports[`Transform: Transform List Minimal initializat
fill={true}
iconType="plusInCircle"
onClick={[MockFunction]}
- size="s"
>
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/create_transform_button.tsx b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/create_transform_button.tsx
index c06be15f259d0..25024d9c5cc08 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/create_transform_button.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/create_transform_button/create_transform_button.tsx
@@ -33,12 +33,11 @@ export const CreateTransformButton: FC = ({ onClick
fill
onClick={onClick}
iconType="plusInCircle"
- size="s"
data-test-subj="transformButtonCreate"
>
);
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/refresh_transform_list_button/refresh_transform_list_button.tsx b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/refresh_transform_list_button/refresh_transform_list_button.tsx
index e8ebc42ecc180..f8a1f84937326 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/refresh_transform_list_button/refresh_transform_list_button.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/refresh_transform_list_button/refresh_transform_list_button.tsx
@@ -6,7 +6,7 @@
import React, { FC } from 'react';
-import { EuiButtonEmpty } from '@elastic/eui';
+import { EuiButton } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
interface RefreshTransformListButton {
@@ -17,14 +17,16 @@ export const RefreshTransformListButton: FC = ({
onClick,
isLoading,
}) => (
-
-
+
);
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx
index 1037fdebbed6a..a7e4e49440089 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx
@@ -14,6 +14,8 @@ import {
EuiButtonIcon,
EuiCallOut,
EuiEmptyPrompt,
+ EuiFlexGroup,
+ EuiFlexItem,
EuiPopover,
EuiTitle,
} from '@elastic/eui';
@@ -21,6 +23,7 @@ import {
import { OnTableChangeArg, SortDirection, SORT_DIRECTION } from '../../../../../shared_imports';
import {
+ useRefreshTransformList,
TransformId,
TransformListRow,
TRANSFORM_MODE,
@@ -28,6 +31,9 @@ import {
TRANSFORM_STATE,
} from '../../../../common';
import { AuthorizationContext } from '../../../../lib/authorization';
+
+import { CreateTransformButton } from '../create_transform_button';
+import { RefreshTransformListButton } from '../refresh_transform_list_button';
import { getTaskStateBadge } from './columns';
import { DeleteAction } from './action_delete';
import { StartAction } from './action_start';
@@ -78,6 +84,8 @@ export const TransformList: FC = ({
transformsLoading,
}) => {
const [isLoading, setIsLoading] = useState(false);
+ const { refresh } = useRefreshTransformList({ isLoading: setIsLoading });
+
const [filterActive, setFilterActive] = useState(false);
const [filteredTransforms, setFilteredTransforms] = useState([]);
@@ -300,8 +308,20 @@ export const TransformList: FC = ({
];
};
+ const renderToolsRight = () => (
+
+
+
+
+
+
+
+
+ );
+
const search = {
toolsLeft: transformSelection.length > 0 ? renderToolsLeft() : undefined,
+ toolsRight: renderToolsRight(),
onChange: onQueryChange,
box: {
incremental: true,
diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
index 2c17446df830b..2e0e930990e6e 100644
--- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
+++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx
@@ -11,17 +11,16 @@ import { i18n } from '@kbn/i18n';
import {
EuiBetaBadge,
+ EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiModal,
EuiOverlayMask,
- EuiPage,
EuiPageBody,
+ EuiPageContent,
EuiPageContentBody,
- EuiPageContentHeader,
- EuiPageContentHeaderSection,
- EuiPanel,
EuiSpacer,
+ EuiText,
EuiTitle,
} from '@elastic/eui';
@@ -31,22 +30,19 @@ import { useGetTransforms } from '../../hooks';
import { RedirectToCreateTransform } from '../../common/navigation';
import { PrivilegesWrapper } from '../../lib/authorization';
import { breadcrumbService, docTitleService, BREADCRUMB_SECTION } from '../../services/navigation';
+import { documentationLinksService } from '../../services/documentation';
import { useRefreshInterval } from './components/transform_list/use_refresh_interval';
-import { CreateTransformButton } from './components/create_transform_button';
-import { RefreshTransformListButton } from './components/refresh_transform_list_button';
import { SearchSelection } from './components/search_selection';
import { TransformList } from './components/transform_list';
import { TransformStatsBar } from './components/transform_list/transforms_stats_bar';
export const TransformManagement: FC = () => {
- const [isLoading, setIsLoading] = useState(false);
const [transformsLoading, setTransformsLoading] = useState(false);
const [isInitialized, setIsInitialized] = useState(false);
const [blockRefresh, setBlockRefresh] = useState(false);
const [transforms, setTransforms] = useState([]);
const [errorMessage, setErrorMessage] = useState(undefined);
- const { refresh } = useRefreshTransformList({ isLoading: setIsLoading });
const getTransforms = useGetTransforms(
setTransforms,
@@ -78,12 +74,12 @@ export const TransformManagement: FC = () => {
return (
-
-
-
-
-
-
+
+
+
+
+
+
{
)}
/>
-
-
-
-
- {/* grow={false} fixes IE11 issue with nested flex */}
-
-
-
- {/* grow={false} fixes IE11 issue with nested flex */}
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
-
+
+
{isSearchSelectionVisible && (
diff --git a/x-pack/legacy/plugins/transform/public/app/services/documentation/documentation_links.ts b/x-pack/legacy/plugins/transform/public/app/services/documentation/documentation_links.ts
index ea44d64600d7c..05eb15f2046a1 100644
--- a/x-pack/legacy/plugins/transform/public/app/services/documentation/documentation_links.ts
+++ b/x-pack/legacy/plugins/transform/public/app/services/documentation/documentation_links.ts
@@ -6,14 +6,14 @@
import { TRANSFORM_DOC_PATHS } from '../../constants';
class DocumentationLinksService {
- private esPluginDocBasePath: string = '';
+ private esDocBasePath: string = '';
- public init(esPluginDocBasePath: string): void {
- this.esPluginDocBasePath = esPluginDocBasePath;
+ public init(esDocBasePath: string): void {
+ this.esDocBasePath = esDocBasePath;
}
- public getTransformPluginDocUrl() {
- return `${this.esPluginDocBasePath}${TRANSFORM_DOC_PATHS.plugins}`;
+ public getTransformsDocUrl() {
+ return `${this.esDocBasePath}${TRANSFORM_DOC_PATHS.transforms}`;
}
}
diff --git a/x-pack/legacy/plugins/transform/public/plugin.ts b/x-pack/legacy/plugins/transform/public/plugin.ts
index 7dfb9daead574..e7cc83d16b3b9 100644
--- a/x-pack/legacy/plugins/transform/public/plugin.ts
+++ b/x-pack/legacy/plugins/transform/public/plugin.ts
@@ -54,7 +54,7 @@ export class Plugin {
textService.init();
breadcrumbService.init(chrome, management.constants.BREADCRUMB);
uiMetricService.init(uiMetric.createUiStatsReporter);
- documentationLinksService.init(documentation.esPluginDocBasePath);
+ documentationLinksService.init(documentation.esDocBasePath);
docTitleService.init(docTitle.change);
const unmountReactApp = (): void => {
From 41aea39cc06b391eb142a937e350337799c528ee Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Mon, 21 Oct 2019 01:47:43 -0700
Subject: [PATCH 002/191] Adds es-ui team to transform plugin in CODEOWNERS.
(#48665)
---
.github/CODEOWNERS | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 012e49690fd15..5680bd8cbf822 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -81,6 +81,9 @@
/x-pack/legacy/plugins/rollup/ @elastic/es-ui
/x-pack/legacy/plugins/searchprofiler/ @elastic/es-ui
/x-pack/legacy/plugins/snapshot_restore/ @elastic/es-ui
+# ML team owns the transform plugin, ES team added here for visibility
+# because the plugin lives in Kibana's Elasticsearch management section.
+/x-pack/legacy/plugins/transform/ @elastic/es-ui
/x-pack/legacy/plugins/watcher/ @elastic/es-ui
# Kibana TSVB external contractors
From fade9ae711d7324f5a7c0231f190d7091a1cc0b3 Mon Sep 17 00:00:00 2001
From: Dima Arnautov
Date: Mon, 21 Oct 2019 12:19:23 +0200
Subject: [PATCH 003/191] [ML] Fix partitioning field value update (#48655)
---
.../timeseriesexplorer/timeseriesexplorer.js | 28 ++++++++++++-------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/timeseriesexplorer/timeseriesexplorer.js b/x-pack/legacy/plugins/ml/public/timeseriesexplorer/timeseriesexplorer.js
index cea2dc37bfad3..44632a2b29928 100644
--- a/x-pack/legacy/plugins/ml/public/timeseriesexplorer/timeseriesexplorer.js
+++ b/x-pack/legacy/plugins/ml/public/timeseriesexplorer/timeseriesexplorer.js
@@ -337,14 +337,22 @@ export class TimeSeriesExplorer extends React.Component {
}
entityFieldValueChanged = (entity, fieldValue) => {
- this.setState(prevState => ({
- entities: prevState.entities.map(stateEntity => {
- if (stateEntity.fieldName === entity.fieldName) {
- stateEntity.fieldValue = fieldValue;
- }
- return stateEntity;
- })
- }), () => this.saveSeriesPropertiesAndRefresh());
+ const { appStateHandler } = this.props;
+ const { entities } = this.state;
+
+ const resultEntities = {
+ ...entities.reduce((appStateEntities, appStateEntity) => {
+ appStateEntities[appStateEntity.fieldName] = appStateEntity.fieldValue;
+ return appStateEntities;
+ }, {}),
+ [entity.fieldName]: fieldValue,
+ };
+
+ appStateHandler(APP_STATE_ACTION.SET_ENTITIES, resultEntities);
+
+ this.updateControlsForDetector(() => {
+ this.refresh();
+ });
};
loadAnomaliesTableData = (earliestMs, latestMs) => {
@@ -1090,11 +1098,11 @@ export class TimeSeriesExplorer extends React.Component {
/>
)}
- {(jobs.length > 0 && (fullRefresh === false || loading === false) && hasResults === false) && (
+ {(jobs.length > 0 && loading === false && hasResults === false) && (
)}
- {(jobs.length > 0 && (fullRefresh === false || loading === false) && hasResults === true) && (
+ {(jobs.length > 0 && loading === false && hasResults === true) && (
{i18n.translate('xpack.ml.timeSeriesExplorer.singleTimeSeriesAnalysisTitle', {
From bb1c3889c5a00b97bb5f29fb4f82efbb14c86afc Mon Sep 17 00:00:00 2001
From: James Gowdy
Date: Mon, 21 Oct 2019 11:42:54 +0100
Subject: [PATCH 004/191] [ML] Filtering advanced detector's aggs and fields
(#48651)
* [ML] Filtering advanced detector's aggs and fields
* adding comments
* fix for EuiComboBox
* better words
* updating tests
---
.../advanced_detector_modal.tsx | 44 +++++++++++++++++--
.../services/new_job_capabilities_service.ts | 13 +++---
.../results/cloudwatch_rollup_job_caps.json | 10 -----
.../__mocks__/results/farequote_job_caps.json | 36 +++++++--------
.../job_service/new_job_caps/aggregations.ts | 23 +++++++---
.../job_service/new_job_caps/field_service.ts | 16 ++-----
.../job_service/new_job_caps/new_job_caps.ts | 6 ++-
7 files changed, 88 insertions(+), 60 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx
index 97fb8c1d41fc5..159f26475256d 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx
@@ -91,11 +91,19 @@ export const AdvancedDetectorModal: FC = ({
const [fieldOptionEnabled, setFieldOptionEnabled] = useState(true);
const { descriptionPlaceholder, setDescriptionPlaceholder } = useDetectorPlaceholder(detector);
- const aggOptions: EuiComboBoxOptionProps[] = aggs.map(createAggOption);
- const fieldOptions: EuiComboBoxOptionProps[] = fields
+ // list of aggregation combobox options. filtering out any aggs with no fields.
+ const aggOptions: EuiComboBoxOptionProps[] = aggs
+ .filter(a => a.fields !== undefined && a.fields.length)
+ .map(createAggOption);
+
+ // fields available for the selected agg
+ const { currentFieldOptions, setCurrentFieldOptions } = useCurrentFieldOptions(detector.agg);
+
+ const allFieldOptions: EuiComboBoxOptionProps[] = fields
.filter(f => f.id !== EVENT_RATE_FIELD_ID)
.map(createFieldOption);
- const splitFieldOptions = [...fieldOptions, ...createMlcategoryField(jobCreator)];
+
+ const splitFieldOptions = [...allFieldOptions, ...createMlcategoryField(jobCreator)];
const eventRateField = fields.find(f => f.id === EVENT_RATE_FIELD_ID);
@@ -124,6 +132,8 @@ export const AdvancedDetectorModal: FC = ({
if (agg !== null) {
setFieldsEnabled(true);
+ setCurrentFieldOptions(agg);
+
if (isFieldlessAgg(agg) && eventRateField !== undefined) {
setFieldOption(emptyOption);
setFieldOptionEnabled(false);
@@ -207,7 +217,7 @@ export const AdvancedDetectorModal: FC = ({
f.id !== EVENT_RATE_FIELD_ID)
+ .map(createFieldOption);
+
+ // working round EuiComboBox's odd behavior when the options list contains only one item
+ return options.length === 1 ? [emptyOption, ...options] : options;
+}
+
+// custom hook for storing combobox options based on an aggregation field list
+function useCurrentFieldOptions(aggregation: Aggregation | null) {
+ const [currentFieldOptions, setCurrentFieldOptions] = useState(
+ createFieldOptionList(aggregation)
+ );
+
+ return {
+ currentFieldOptions,
+ setCurrentFieldOptions: (agg: Aggregation | null) =>
+ setCurrentFieldOptions(createFieldOptionList(agg)),
+ };
+}
+
function createDefaultDescription(dtr: RichDetector) {
if (dtr.agg === null || dtr.field === null) {
return '';
diff --git a/x-pack/legacy/plugins/ml/public/services/new_job_capabilities_service.ts b/x-pack/legacy/plugins/ml/public/services/new_job_capabilities_service.ts
index f2639029f6377..890683793339a 100644
--- a/x-pack/legacy/plugins/ml/public/services/new_job_capabilities_service.ts
+++ b/x-pack/legacy/plugins/ml/public/services/new_job_capabilities_service.ts
@@ -126,17 +126,18 @@ function createObjects(resp: any, indexPatternTitle: string) {
if (results !== undefined) {
results.aggs.forEach((a: Aggregation) => {
- // copy the agg and add a Fields list
+ // create the aggs list
+ // only adding a fields list if there is a fieldIds list
const agg: Aggregation = {
...a,
- fields: [],
+ ...(a.fieldIds !== undefined ? { fields: [] } : {}),
};
aggMap[agg.id] = agg;
aggs.push(agg);
});
results.fields.forEach((f: Field) => {
- // copy the field and add an Aggregations list
+ // create the fields list
const field: Field = {
...f,
aggs: [],
@@ -188,8 +189,10 @@ function addEventRateField(aggs: Aggregation[], fields: Field[]) {
};
aggs.forEach(a => {
- if (a.fields !== undefined && eventRateField.aggs !== undefined && a.fields.length === 0) {
- a.fields.push(eventRateField);
+ if (eventRateField.aggs !== undefined && a.fields === undefined) {
+ // if the agg's field list is undefined, it is a fieldless aggregation and
+ // so can only be used with the event rate field.
+ a.fields = [eventRateField];
eventRateField.aggs.push(a);
}
});
diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/cloudwatch_rollup_job_caps.json b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/cloudwatch_rollup_job_caps.json
index bf5228861967b..ae940ffbf4828 100644
--- a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/cloudwatch_rollup_job_caps.json
+++ b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/cloudwatch_rollup_job_caps.json
@@ -3,7 +3,6 @@
"aggs": [
{
"dslName": "count",
- "fieldIds": [],
"id": "count",
"kibanaName": "count",
"mlModelPlotAgg": {
@@ -15,7 +14,6 @@
},
{
"dslName": "count",
- "fieldIds": [],
"id": "high_count",
"kibanaName": "count",
"mlModelPlotAgg": {
@@ -27,7 +25,6 @@
},
{
"dslName": "count",
- "fieldIds": [],
"id": "low_count",
"kibanaName": "count",
"mlModelPlotAgg": {
@@ -183,7 +180,6 @@
},
{
"dslName": null,
- "fieldIds": [],
"id": "non_zero_count",
"kibanaName": null,
"mlModelPlotAgg": {
@@ -195,7 +191,6 @@
},
{
"dslName": null,
- "fieldIds": [],
"id": "high_non_zero_count",
"kibanaName": null,
"mlModelPlotAgg": {
@@ -207,7 +202,6 @@
},
{
"dslName": null,
- "fieldIds": [],
"id": "low_non_zero_count",
"kibanaName": null,
"mlModelPlotAgg": {
@@ -327,7 +321,6 @@
},
{
"dslName": null,
- "fieldIds": [],
"id": "rare",
"kibanaName": null,
"mlModelPlotAgg": {
@@ -339,7 +332,6 @@
},
{
"dslName": null,
- "fieldIds": [],
"id": "freq_rare",
"kibanaName": null,
"mlModelPlotAgg": {
@@ -387,7 +379,6 @@
},
{
"dslName": null,
- "fieldIds": [],
"id": "time_of_day",
"kibanaName": null,
"mlModelPlotAgg": {
@@ -399,7 +390,6 @@
},
{
"dslName": null,
- "fieldIds": [],
"id": "time_of_week",
"kibanaName": null,
"mlModelPlotAgg": {
diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/farequote_job_caps.json b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/farequote_job_caps.json
index cff91d90e8ffc..99c373eddd107 100644
--- a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/farequote_job_caps.json
+++ b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/__mocks__/results/farequote_job_caps.json
@@ -10,8 +10,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "high_count",
@@ -22,8 +21,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "low_count",
@@ -34,8 +32,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "mean",
@@ -215,8 +212,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "high_non_zero_count",
@@ -227,8 +223,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "low_non_zero_count",
@@ -239,8 +234,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "high_distinct_count",
@@ -253,6 +247,7 @@
"min": "min"
},
"fieldIds": [
+ "airline",
"responsetime"
]
},
@@ -267,6 +262,7 @@
"min": "min"
},
"fieldIds": [
+ "airline",
"responsetime"
]
},
@@ -377,8 +373,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "freq_rare",
@@ -389,8 +384,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "info_content",
@@ -443,8 +437,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "time_of_week",
@@ -455,8 +448,7 @@
"mlModelPlotAgg": {
"max": "max",
"min": "min"
- },
- "fieldIds": []
+ }
},
{
"id": "lat_long",
@@ -487,7 +479,9 @@
"type": "keyword",
"aggregatable": true,
"aggIds": [
- "distinct_count"
+ "distinct_count",
+ "high_distinct_count",
+ "low_distinct_count"
]
},
{
diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/aggregations.ts b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/aggregations.ts
index 5a10eb0eed7aa..efe06f8b5ad4a 100644
--- a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/aggregations.ts
+++ b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/aggregations.ts
@@ -11,9 +11,9 @@ import {
ES_AGGREGATION,
} from '../../../../common/constants/aggregation_types';
-// aggregation object missing id and title and has null for kibana and dsl aggregation names.
+// aggregation object missing id, title and fields and has null for kibana and dsl aggregation names.
// this is used as the basis for the ML only aggregations
-function getBasicMlOnlyAggregation(): Omit {
+function getBasicMlOnlyAggregation(): Omit {
return {
kibanaName: null,
dslName: null,
@@ -22,10 +22,11 @@ function getBasicMlOnlyAggregation(): Omit {
max: KIBANA_AGGREGATION.MAX,
min: KIBANA_AGGREGATION.MIN,
},
- fields: [],
};
}
+// list of aggregations only support by ML and which don't have an equivalent ES aggregation
+// note, not all aggs have a field list. Some aggs cannot be used with a field.
export const mlOnlyAggregations: Aggregation[] = [
{
id: ML_JOB_AGGREGATION.NON_ZERO_COUNT,
@@ -45,46 +46,55 @@ export const mlOnlyAggregations: Aggregation[] = [
{
id: ML_JOB_AGGREGATION.HIGH_DISTINCT_COUNT,
title: 'High distinct count',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.LOW_DISTINCT_COUNT,
title: 'Low distinct count',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.METRIC,
title: 'Metric',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.VARP,
title: 'varp',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.HIGH_VARP,
title: 'High varp',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.LOW_VARP,
title: 'Low varp',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.NON_NULL_SUM,
title: 'Non null sum',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.HIGH_NON_NULL_SUM,
title: 'High non null sum',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.LOW_NON_NULL_SUM,
title: 'Low non null sum',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
@@ -100,16 +110,19 @@ export const mlOnlyAggregations: Aggregation[] = [
{
id: ML_JOB_AGGREGATION.INFO_CONTENT,
title: 'Info content',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.HIGH_INFO_CONTENT,
title: 'High info content',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
id: ML_JOB_AGGREGATION.LOW_INFO_CONTENT,
title: 'Low info content',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
{
@@ -125,6 +138,7 @@ export const mlOnlyAggregations: Aggregation[] = [
{
id: ML_JOB_AGGREGATION.LAT_LONG,
title: 'Lat long',
+ fields: [],
...getBasicMlOnlyAggregation(),
},
];
@@ -140,7 +154,6 @@ export const aggregations: Aggregation[] = [
max: KIBANA_AGGREGATION.MAX,
min: KIBANA_AGGREGATION.MIN,
},
- fields: [],
},
{
id: ML_JOB_AGGREGATION.HIGH_COUNT,
@@ -152,7 +165,6 @@ export const aggregations: Aggregation[] = [
max: KIBANA_AGGREGATION.MAX,
min: KIBANA_AGGREGATION.MIN,
},
- fields: [],
},
{
id: ML_JOB_AGGREGATION.LOW_COUNT,
@@ -164,7 +176,6 @@ export const aggregations: Aggregation[] = [
max: KIBANA_AGGREGATION.MAX,
min: KIBANA_AGGREGATION.MIN,
},
- fields: [],
},
{
id: ML_JOB_AGGREGATION.MEAN,
diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/field_service.ts b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/field_service.ts
index 7e5ab342c5a08..df4a2c059f1ef 100644
--- a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/field_service.ts
+++ b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/field_service.ts
@@ -139,21 +139,11 @@ async function combineFieldsAndAggs(
const mix = mixFactory(rollupFields);
aggs.forEach(a => {
- if (a.type === METRIC_AGG_TYPE) {
+ if (a.type === METRIC_AGG_TYPE && a.fields !== undefined) {
switch (a.id) {
- case ML_JOB_AGGREGATION.COUNT:
- case ML_JOB_AGGREGATION.HIGH_COUNT:
- case ML_JOB_AGGREGATION.LOW_COUNT:
- case ML_JOB_AGGREGATION.NON_ZERO_COUNT:
- case ML_JOB_AGGREGATION.HIGH_NON_ZERO_COUNT:
- case ML_JOB_AGGREGATION.LOW_NON_ZERO_COUNT:
- case ML_JOB_AGGREGATION.RARE:
- case ML_JOB_AGGREGATION.FREQ_RARE:
- case ML_JOB_AGGREGATION.TIME_OF_DAY:
- case ML_JOB_AGGREGATION.TIME_OF_WEEK:
- // functions which do not take any fields, so break here
- break;
case ML_JOB_AGGREGATION.DISTINCT_COUNT:
+ case ML_JOB_AGGREGATION.HIGH_DISTINCT_COUNT:
+ case ML_JOB_AGGREGATION.LOW_DISTINCT_COUNT:
// distinct count (i.e. cardinality) takes keywords, ips
// as well as numerical fields
keywordFields.forEach(f => {
diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts
index 798790e1d37c3..cbb249be09aa0 100644
--- a/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts
+++ b/x-pack/legacy/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.ts
@@ -42,7 +42,11 @@ function convertForStringify(aggs: Aggregation[], fields: Field[]): void {
delete f.aggs;
});
aggs.forEach(a => {
- a.fieldIds = a.fields ? a.fields.map(f => f.id) : [];
+ if (a.fields !== undefined) {
+ // if the aggregation supports fields, i.e. it's fields list isn't undefined,
+ // create a list of field ids
+ a.fieldIds = a.fields.map(f => f.id);
+ }
delete a.fields;
});
}
From 4895f16108ff1768340471428a23841b36e3a80c Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Mon, 21 Oct 2019 03:52:22 -0700
Subject: [PATCH 005/191] [ML] Fix analytics source index selection. (#48731)
Fixes the empty dropdown when only one Kibana index pattern is available. Root cause of the issue: When no index is selected we passed in an selection item with an empty label. Internally EuiComboBox doesn't check if that item matches one of the available options, it just compares the length of selected and available options. So with one empty option selected and one index pattern available the dropdown would say You've selected all available options. This PR fixes it by checking if the current selection is actually part of the available index patterns. If it's an empty string for example, an empty array will be passed to the component instead of an empty with an item with an empty label.
---
.../create_analytics_form/create_analytics_form.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx
index a32631c707f55..35a0e1c82cf33 100644
--- a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx
+++ b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/create_analytics_form/create_analytics_form.tsx
@@ -239,7 +239,9 @@ export const CreateAnalyticsForm: FC = ({ actions, sta
)}
singleSelection={{ asPlainText: true }}
options={indexPatternTitles.sort().map(d => ({ label: d }))}
- selectedOptions={[{ label: sourceIndex }]}
+ selectedOptions={
+ indexPatternTitles.includes(sourceIndex) ? [{ label: sourceIndex }] : []
+ }
onChange={selectedOptions =>
setFormState({ sourceIndex: selectedOptions[0].label || '' })
}
From e4ecfb105d9d55a46dd2cd80cfab3f48bed7bead Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez?=
Date: Mon, 21 Oct 2019 13:28:21 +0200
Subject: [PATCH 006/191] Handle empty datafeedState (#48660)
---
.../containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts | 1 +
.../containers/logs/log_analysis/log_analysis_status_state.tsx | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts b/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts
index 477e75fc3b90c..6171d10b5f1aa 100644
--- a/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts
+++ b/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts
@@ -39,6 +39,7 @@ export type FetchJobStatusRequestPayload = rt.TypeOf (jobSummaries: FetchJobStatusResponsePay
.filter(jobSummary => jobSummary.id === jobId)
.map(
(jobSummary): JobStatus => {
- if (jobSummary.jobState === 'failed') {
+ if (jobSummary.jobState === 'failed' || jobSummary.datafeedState === '') {
return 'failed';
} else if (
jobSummary.jobState === 'closed' &&
From 3cfbfaffd59a818d67fe8f197f10e4f6c860e2d3 Mon Sep 17 00:00:00 2001
From: Daniil Suleiman <31325372+sulemanof@users.noreply.github.com>
Date: Mon, 21 Oct 2019 15:23:39 +0300
Subject: [PATCH 007/191] Add keys in NewVisHelp render (#48619)
---
.../public/visualize/wizard/type_selection/new_vis_help.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx
index 7e1a49c088d54..3877c01dcc672 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx
+++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/type_selection/new_vis_help.tsx
@@ -18,7 +18,7 @@
*/
import { FormattedMessage } from '@kbn/i18n/react';
-import React from 'react';
+import React, { Fragment } from 'react';
import { EuiText, EuiButton } from '@elastic/eui';
import chrome from 'ui/chrome';
import { VisTypeAliasListEntry } from './type_selection';
@@ -37,7 +37,7 @@ export function NewVisHelp(props: Props) {
/>
{props.promotedTypes.map(t => (
- <>
+
{t.promotion!.description}
@@ -50,7 +50,7 @@ export function NewVisHelp(props: Props) {
>
{t.promotion!.buttonText}
- >
+
))}
);
From 28c374ace558b2d46ce360a098e866e51bf0c851 Mon Sep 17 00:00:00 2001
From: James Gowdy
Date: Mon, 21 Oct 2019 14:07:02 +0100
Subject: [PATCH 008/191] [ML] Fix detector modal combo box selection (#48741)
* [ML] Fix detector modal combo box selection
* removing old work around
---
.../advanced_detector_modal.tsx | 23 ++++++++++++-------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx
index 159f26475256d..142de85e97565 100644
--- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx
+++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/pick_fields_step/components/advanced_detector_modal/advanced_detector_modal.tsx
@@ -218,7 +218,7 @@ export const AdvancedDetectorModal: FC = ({
= ({
= ({
= ({
f.id !== EVENT_RATE_FIELD_ID)
.map(createFieldOption);
-
- // working round EuiComboBox's odd behavior when the options list contains only one item
- return options.length === 1 ? [emptyOption, ...options] : options;
}
// custom hook for storing combobox options based on an aggregation field list
@@ -387,3 +384,13 @@ function createDefaultDescription(dtr: RichDetector) {
basicDetector.exclude_frequent = dtr.excludeFrequent ? dtr.excludeFrequent : undefined;
return detectorToString(basicDetector);
}
+
+// fixes issue with EuiComboBox.
+// if the options list only contains one option and nothing has been selected, set
+// selectedOptions list to be an empty array
+function createSelectedOptions(
+ option: EuiComboBoxOptionProps,
+ options: EuiComboBoxOptionProps[]
+): EuiComboBoxOptionProps[] {
+ return options.length === 1 && options[0].label !== option.label ? [] : [option];
+}
From 85e5885ccfbf1c145e21230ca8d878ee9aae6533 Mon Sep 17 00:00:00 2001
From: Brandon Kobel
Date: Mon, 21 Oct 2019 06:35:11 -0700
Subject: [PATCH 009/191] No response compression when there is a referer
(#47751)
* Hacking it in there, this is obviously not where this belongs
* Moving implementation to a private method
* Adding unit tests, I don't like the way I had to write these
* Adding integration tests
* Test not relying on implementation details...
* No longer using .inject, thanks Mikhail!!!
* Adding comment explaining the long body
* Fixing nesting of describes for api integration tests
---
src/core/server/http/http_server.test.ts | 39 ++++++++++++++++++++
src/core/server/http/http_server.ts | 18 ++++++++++
test/api_integration/apis/core/index.js | 46 ++++++++++++++++++------
test/api_integration/apis/index.js | 1 +
4 files changed, 93 insertions(+), 11 deletions(-)
diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts
index acae9d8ff0e70..f61371c5437e6 100644
--- a/src/core/server/http/http_server.test.ts
+++ b/src/core/server/http/http_server.test.ts
@@ -577,6 +577,45 @@ test('exposes route details of incoming request to a route handler', async () =>
});
});
+describe('conditional compression', () => {
+ test('disables compression when there is a referer', async () => {
+ const { registerRouter, server: innerServer } = await server.setup(config);
+
+ const router = new Router('', logger, enhanceWithContext);
+ router.get({ path: '/', validate: false }, (context, req, res) =>
+ // we need the large body here so that compression would normally be used
+ res.ok({ body: 'hello'.repeat(500), headers: { 'Content-Type': 'text/html; charset=UTF-8' } })
+ );
+ registerRouter(router);
+
+ await server.start();
+ const response = await supertest(innerServer.listener)
+ .get('/')
+ .set('accept-encoding', 'gzip')
+ .set('referer', 'http://some-other-site/');
+
+ expect(response.header).not.toHaveProperty('content-encoding');
+ });
+
+ test(`enables compression when there isn't a referer`, async () => {
+ const { registerRouter, server: innerServer } = await server.setup(config);
+
+ const router = new Router('', logger, enhanceWithContext);
+ router.get({ path: '/', validate: false }, (context, req, res) =>
+ // we need the large body here so that compression will be used
+ res.ok({ body: 'hello'.repeat(500), headers: { 'Content-Type': 'text/html; charset=UTF-8' } })
+ );
+ registerRouter(router);
+
+ await server.start();
+ const response = await supertest(innerServer.listener)
+ .get('/')
+ .set('accept-encoding', 'gzip');
+
+ expect(response.header).toHaveProperty('content-encoding', 'gzip');
+ });
+});
+
describe('setup contract', () => {
describe('#createSessionStorage', () => {
it('creates session storage factory', async () => {
diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts
index 3354324c12407..d6077200d3c75 100644
--- a/src/core/server/http/http_server.ts
+++ b/src/core/server/http/http_server.ts
@@ -96,6 +96,7 @@ export class HttpServer {
const basePathService = new BasePath(config.basePath);
this.setupBasePathRewrite(config, basePathService);
+ this.setupConditionalCompression();
return {
registerRouter: this.registerRouter.bind(this),
@@ -175,6 +176,23 @@ export class HttpServer {
});
}
+ private setupConditionalCompression() {
+ if (this.server === undefined) {
+ throw new Error('Server is not created yet');
+ }
+
+ this.server.ext('onRequest', (request, h) => {
+ // whenever there is a referrer, don't use compression even if the client supports it
+ if (request.info.referrer !== '') {
+ this.log.debug(
+ `Not using compression because there is a referer: ${request.info.referrer}`
+ );
+ request.info.acceptEncoding = '';
+ }
+ return h.continue;
+ });
+ }
+
private registerOnPostAuth(fn: OnPostAuthHandler) {
if (this.server === undefined) {
throw new Error('Server is not created yet');
diff --git a/test/api_integration/apis/core/index.js b/test/api_integration/apis/core/index.js
index d617b2ad07351..e5da4e4730662 100644
--- a/test/api_integration/apis/core/index.js
+++ b/test/api_integration/apis/core/index.js
@@ -16,21 +16,45 @@
* specific language governing permissions and limitations
* under the License.
*/
+import expect from '@kbn/expect';
export default function ({ getService }) {
const supertest = getService('supertest');
- describe('core request context', () => {
- it('provides access to elasticsearch', async () => (
- await supertest
- .get('/requestcontext/elasticsearch')
- .expect(200, 'Elasticsearch: true')
- ));
+ describe('core', () => {
+ describe('request context', () => {
+ it('provides access to elasticsearch', async () => (
+ await supertest
+ .get('/requestcontext/elasticsearch')
+ .expect(200, 'Elasticsearch: true')
+ ));
- it('provides access to SavedObjects client', async () => (
- await supertest
- .get('/requestcontext/savedobjectsclient')
- .expect(200, 'SavedObjects client: {"page":1,"per_page":20,"total":0,"saved_objects":[]}')
- ));
+ it('provides access to SavedObjects client', async () => (
+ await supertest
+ .get('/requestcontext/savedobjectsclient')
+ .expect(200, 'SavedObjects client: {"page":1,"per_page":20,"total":0,"saved_objects":[]}')
+ ));
+ });
+
+ describe('compression', () => {
+ it(`uses compression when there isn't a referer`, async () => {
+ await supertest
+ .get('/app/kibana')
+ .set('accept-encoding', 'gzip')
+ .then(response => {
+ expect(response.headers).to.have.property('content-encoding', 'gzip');
+ });
+ });
+
+ it(`doesn't use compression when there is a referer`, async () => {
+ await supertest
+ .get('/app/kibana')
+ .set('accept-encoding', 'gzip')
+ .set('referer', 'https://www.google.com')
+ .then(response => {
+ expect(response.headers).not.to.have.property('content-encoding');
+ });
+ });
+ });
});
}
diff --git a/test/api_integration/apis/index.js b/test/api_integration/apis/index.js
index 9f2672959390c..de36ee678b10e 100644
--- a/test/api_integration/apis/index.js
+++ b/test/api_integration/apis/index.js
@@ -34,5 +34,6 @@ export default function ({ loadTestFile }) {
loadTestFile(require.resolve('./status'));
loadTestFile(require.resolve('./stats'));
loadTestFile(require.resolve('./ui_metric'));
+ loadTestFile(require.resolve('./core'));
});
}
From 4fe73779eedbc79aab45b46f771d9c740db67600 Mon Sep 17 00:00:00 2001
From: Walter Rafelsberger
Date: Mon, 21 Oct 2019 07:05:43 -0700
Subject: [PATCH 010/191] [ML] Fix sidebar links. (#48662)
Fixes missing links to the "What is Elasticsearch Machine Learning"-Page as well as an internal Kibana link to Transforms (Transforms were previously part of the ML main menu but are now moved to the Kibana management section so existing users might miss it otherwise).
---
.../ml/public/overview/components/sidebar.tsx | 22 ++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/x-pack/legacy/plugins/ml/public/overview/components/sidebar.tsx b/x-pack/legacy/plugins/ml/public/overview/components/sidebar.tsx
index 26b67c7774978..5a25f9ad54aa1 100644
--- a/x-pack/legacy/plugins/ml/public/overview/components/sidebar.tsx
+++ b/x-pack/legacy/plugins/ml/public/overview/components/sidebar.tsx
@@ -7,12 +7,15 @@
import React, { FC } from 'react';
import { EuiFlexItem, EuiLink, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
+import chrome from 'ui/chrome';
import { metadata } from 'ui/metadata';
const createJobLink = '#/jobs/new_job/step/index_or_search';
// metadata.branch corresponds to the version used in documentation links.
const docsLink = `https://www.elastic.co/guide/en/kibana/${metadata.branch}/xpack-ml.html`;
const feedbackLink = 'https://www.elastic.co/community/';
+const transformsLink = `${chrome.getBasePath()}/app/kibana#/management/elasticsearch/transform`;
+const whatIsMachineLearningLink = 'https://www.elastic.co/what-is/elasticsearch-machine-learning';
export const OverviewSideBar: FC = () => (
@@ -27,7 +30,8 @@ export const OverviewSideBar: FC = () => (
@@ -45,6 +49,22 @@ export const OverviewSideBar: FC = () => (
/>
),
+ transforms: (
+
+
+
+ ),
+ whatIsMachineLearning: (
+
+
+
+ ),
}}
/>
From 931604d8abf28f7c628198f53491a75fa960ebf7 Mon Sep 17 00:00:00 2001
From: Artyom Gospodarsky
Date: Mon, 21 Oct 2019 18:14:55 +0300
Subject: [PATCH 011/191] Remove extra Field Format wrappers and move into data
plugin (#47948)
* Remove extra wrappers
* Move Field Format utils into data plugin
* Change i18n prefix
* Add a new alias to i18n
* Fix issues
* Make Numeral utils on their own
* Enhance Numeral interface
* Revert Percent changes
* Add common Numeral for Number, Bite, Percent
* Fix i18n for some utils
* Remove test duplicates
* Remove test duplicates
* Make a common import public path
* Reimport default color
* Change paths for server modules
* Change default color constant name
---
.i18nrc.json | 2 +-
.../common/field_formats/types/_numeral.ts | 87 -------
.../common/field_formats/types/boolean.ts | 54 -----
.../common/field_formats/types/color.ts | 75 ------
.../kibana/common/field_formats/types/date.ts | 82 -------
.../common/field_formats/types/date_server.ts | 92 --------
.../common/field_formats/types/source.ts | 83 -------
.../common/field_formats/types/string.ts | 136 -----------
.../kibana/common/field_formats/types/url.ts | 207 ----------------
.../field_formats/__tests__/_boolean.js | 76 ------
.../public/field_formats/__tests__/_color.js | 90 -------
.../public/field_formats/__tests__/_date.js | 71 ------
.../field_formats/__tests__/_duration.js | 62 -----
.../public/field_formats/__tests__/_source.js | 60 -----
.../public/field_formats/__tests__/_string.js | 71 ------
.../field_formats/__tests__/_truncate.js | 52 -----
.../public/field_formats/__tests__/_url.js | 221 ------------------
.../kibana/public/field_formats/register.js | 62 ++---
.../kibana/server/field_formats/register.js | 62 ++---
.../mixin/field_formats_mixin.ts | 8 +-
.../mixin/field_formats_service.test.ts | 5 +-
.../mixin/field_formats_service.ts | 6 +-
.../editors/color/color.js | 4 +-
.../editors/color/color.test.js | 4 +-
.../lib/__tests__/get_default_format.test.js | 9 +-
.../ui/public/registry/field_formats.js | 7 +-
.../field_formats/constants}/color_default.ts | 2 +-
.../common/field_formats/constants/index.ts} | 13 +-
.../field_formats/converters}/boolean.test.ts | 4 +-
.../field_formats/converters/boolean.ts | 50 ++++
.../field_formats/converters}/bytes.test.ts | 4 +-
.../common/field_formats/converters}/bytes.ts | 13 +-
.../field_formats/converters}/color.test.ts | 6 +-
.../common/field_formats/converters/color.ts | 69 ++++++
.../field_formats/converters}/date.test.ts | 4 +-
.../common/field_formats/converters/date.ts | 76 ++++++
.../converters}/date_nanos.test.ts | 6 +-
.../field_formats/converters}/date_nanos.ts | 106 ++++-----
.../field_formats/converters/date_server.ts | 88 +++++++
.../converters}/duration.test.ts | 4 +-
.../field_formats/converters}/duration.ts | 102 ++++----
.../common/field_formats/converters/index.ts} | 37 ++-
.../field_formats/converters}/ip.test.ts | 4 +-
.../common/field_formats/converters/ip.ts} | 28 +--
.../field_formats/converters}/number.test.ts | 4 +-
.../field_formats/converters}/number.ts | 13 +-
.../field_formats/converters/numeral.ts | 74 ++++++
.../field_formats/converters}/percent.test.ts | 4 +-
.../field_formats/converters}/percent.ts | 34 +--
.../converters}/relative_date.test.ts | 4 +-
.../converters}/relative_date.ts | 48 ++--
.../field_formats/converters/source.test.ts | 45 ++++
.../common/field_formats/converters/source.ts | 76 ++++++
.../converters}/static_lookup.ts | 50 ++--
.../field_formats/converters}/string.test.ts | 4 +-
.../common/field_formats/converters/string.ts | 130 +++++++++++
.../converters}/truncate.test.ts | 4 +-
.../field_formats/converters}/truncate.ts | 40 ++--
.../field_formats/converters}/url.test.ts | 6 +-
.../common/field_formats/converters/url.ts | 202 ++++++++++++++++
.../data/common/field_formats/index.ts | 2 +
.../legacy/plugins/apm/typings/numeral.d.ts | 2 +
.../csv/server/__tests__/execute_job.js | 4 +-
.../server/lib/__tests__/field_format_map.js | 5 +-
64 files changed, 1146 insertions(+), 1909 deletions(-)
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/_numeral.ts
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/boolean.ts
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/color.ts
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/date.ts
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/date_server.ts
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/source.ts
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/string.ts
delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/url.ts
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_boolean.js
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_color.js
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_date.js
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_duration.js
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_source.js
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_string.js
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_truncate.js
delete mode 100644 src/legacy/core_plugins/kibana/public/field_formats/__tests__/_url.js
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/constants}/color_default.ts (95%)
rename src/{legacy/core_plugins/kibana/public/field_formats/__tests__/index.js => plugins/data/common/field_formats/constants/index.ts} (76%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/boolean.test.ts (95%)
create mode 100644 src/plugins/data/common/field_formats/converters/boolean.ts
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/bytes.test.ts (93%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/bytes.ts (80%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/color.test.ts (96%)
create mode 100644 src/plugins/data/common/field_formats/converters/color.ts
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/date.test.ts (96%)
create mode 100644 src/plugins/data/common/field_formats/converters/date.ts
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/date_nanos.test.ts (95%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/date_nanos.ts (56%)
create mode 100644 src/plugins/data/common/field_formats/converters/date_server.ts
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/duration.test.ts (96%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/duration.ts (50%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types/ip.ts => plugins/data/common/field_formats/converters/index.ts} (55%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/ip.test.ts (94%)
rename src/{legacy/core_plugins/kibana/public/field_formats/__tests__/_ip.js => plugins/data/common/field_formats/converters/ip.ts} (57%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/number.test.ts (93%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/number.ts (80%)
create mode 100644 src/plugins/data/common/field_formats/converters/numeral.ts
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/percent.test.ts (93%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/percent.ts (57%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/relative_date.test.ts (92%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/relative_date.ts (55%)
create mode 100644 src/plugins/data/common/field_formats/converters/source.test.ts
create mode 100644 src/plugins/data/common/field_formats/converters/source.ts
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/static_lookup.ts (56%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/string.test.ts (96%)
create mode 100644 src/plugins/data/common/field_formats/converters/string.ts
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/truncate.test.ts (94%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/truncate.ts (58%)
rename src/{legacy/core_plugins/kibana/common/field_formats/types => plugins/data/common/field_formats/converters}/url.test.ts (98%)
create mode 100644 src/plugins/data/common/field_formats/converters/url.ts
diff --git a/.i18nrc.json b/.i18nrc.json
index b8bd8729139c0..0ea51fe8212c4 100644
--- a/.i18nrc.json
+++ b/.i18nrc.json
@@ -1,7 +1,7 @@
{
"paths": {
"common.ui": "src/legacy/ui",
- "data": "src/legacy/core_plugins/data",
+ "data": ["src/legacy/core_plugins/data", "src/plugins/data"],
"expressions": "src/legacy/core_plugins/expressions",
"kibana_react": "src/legacy/core_plugins/kibana_react",
"server": "src/legacy/server",
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/_numeral.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/_numeral.ts
deleted file mode 100644
index 0d39075a1dec9..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/_numeral.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// @ts-ignore
-import numeral from '@elastic/numeral';
-// @ts-ignore
-import numeralLanguages from '@elastic/numeral/languages';
-import { assign, has } from 'lodash';
-import {
- FieldFormat,
- KBN_FIELD_TYPES,
- TextContextTypeConvert,
-} from '../../../../../../plugins/data/common/';
-
-const numeralInst = numeral();
-
-numeralLanguages.forEach(function(numeralLanguage: Record) {
- numeral.language(numeralLanguage.id, numeralLanguage.lang);
-});
-
-export function createNumeralFormat(opts: Record) {
- class NumeralFormat extends FieldFormat {
- static id = opts.id;
- static title = opts.title;
- static fieldType = KBN_FIELD_TYPES.NUMBER;
-
- private getConfig: Function;
-
- constructor(params: Record, getConfig: Function) {
- super(params);
- this.getConfig = getConfig;
- }
-
- getParamDefaults() {
- if (has(opts, 'getParamDefaults')) {
- return opts.getParamDefaults(this.getConfig);
- }
-
- return {
- pattern: this.getConfig(`format:${opts.id}:defaultPattern`),
- };
- }
-
- textConvert: TextContextTypeConvert = val => {
- if (val === -Infinity) return '-∞';
- if (val === +Infinity) return '+∞';
- if (typeof val !== 'number') {
- val = parseFloat(val);
- }
-
- if (isNaN(val)) return '';
-
- const previousLocale = numeral.language();
- const defaultLocale =
- (this.getConfig && this.getConfig('format:number:defaultLocale')) || 'en';
- numeral.language(defaultLocale);
-
- const formatted = numeralInst.set(val).format(this.param('pattern'));
-
- numeral.language(previousLocale);
-
- return opts.afterConvert ? opts.afterConvert.call(this, formatted) : formatted;
- };
- }
-
- if (opts.prototype) {
- assign(NumeralFormat.prototype, opts.prototype);
- }
-
- return NumeralFormat;
-}
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/boolean.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/boolean.ts
deleted file mode 100644
index 840bf20a9af35..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/boolean.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import {
- FieldFormat,
- asPrettyString,
- KBN_FIELD_TYPES,
- TextContextTypeConvert,
-} from '../../../../../../plugins/data/common';
-
-export function createBoolFormat() {
- return class BoolFormat extends FieldFormat {
- static id = 'boolean';
- static title = 'Boolean';
- static fieldType = [KBN_FIELD_TYPES.BOOLEAN, KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.STRING];
-
- textConvert: TextContextTypeConvert = value => {
- if (typeof value === 'string') {
- value = value.trim().toLowerCase();
- }
-
- switch (value) {
- case false:
- case 0:
- case 'false':
- case 'no':
- return 'false';
- case true:
- case 1:
- case 'true':
- case 'yes':
- return 'true';
- default:
- return asPrettyString(value);
- }
- };
- };
-}
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/color.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/color.ts
deleted file mode 100644
index 065918c6bbdf2..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/color.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { findLast, cloneDeep, template, escape } from 'lodash';
-import {
- asPrettyString,
- FieldFormat,
- KBN_FIELD_TYPES,
- HtmlContextTypeConvert,
-} from '../../../../../../plugins/data/common/';
-import { DEFAULT_COLOR } from './color_default';
-
-const convertTemplate = template('<%- val %>');
-
-export function createColorFormat() {
- class ColorFormat extends FieldFormat {
- static id = 'color';
- static title = 'Color';
- static fieldType = [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.STRING];
-
- getParamDefaults() {
- return {
- fieldType: null, // populated by editor, see controller below
- colors: [cloneDeep(DEFAULT_COLOR)],
- };
- }
-
- findColorRuleForVal(val: any) {
- switch (this.param('fieldType')) {
- case 'string':
- return findLast(this.param('colors'), (colorParam: typeof DEFAULT_COLOR) => {
- return new RegExp(colorParam.regex).test(val);
- });
-
- case 'number':
- return findLast(this.param('colors'), ({ range }) => {
- if (!range) return;
- const [start, end] = range.split(':');
- return val >= Number(start) && val <= Number(end);
- });
-
- default:
- return null;
- }
- }
-
- htmlConvert: HtmlContextTypeConvert = val => {
- const color = this.findColorRuleForVal(val) as typeof DEFAULT_COLOR;
- if (!color) return escape(asPrettyString(val));
-
- let style = '';
- if (color.text) style += `color: ${color.text};`;
- if (color.background) style += `background-color: ${color.background};`;
- return convertTemplate({ val, style });
- };
- }
-
- return ColorFormat;
-}
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/date.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/date.ts
deleted file mode 100644
index b04a1729ee13e..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/date.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { memoize, noop } from 'lodash';
-import moment from 'moment';
-import {
- FieldFormat,
- KBN_FIELD_TYPES,
- TextContextTypeConvert,
-} from '../../../../../../plugins/data/common/';
-
-export function createDateFormat() {
- return class DateFormat extends FieldFormat {
- static id = 'date';
- static title = 'Date';
- static fieldType = KBN_FIELD_TYPES.DATE;
-
- private getConfig: Function;
- private memoizedConverter: Function = noop;
- private memoizedPattern: string = '';
- private timeZone: string = '';
-
- constructor(params: Record, getConfig: Function) {
- super(params);
-
- this.getConfig = getConfig;
- }
-
- getParamDefaults() {
- return {
- pattern: this.getConfig('dateFormat'),
- timezone: this.getConfig('dateFormat:tz'),
- };
- }
-
- textConvert: TextContextTypeConvert = val => {
- // don't give away our ref to converter so
- // we can hot-swap when config changes
- const pattern = this.param('pattern');
- const timezone = this.param('timezone');
-
- const timezoneChanged = this.timeZone !== timezone;
- const datePatternChanged = this.memoizedPattern !== pattern;
- if (timezoneChanged || datePatternChanged) {
- this.timeZone = timezone;
- this.memoizedPattern = pattern;
-
- this.memoizedConverter = memoize(function converter(value: any) {
- if (value === null || value === undefined) {
- return '-';
- }
-
- const date = moment(value);
-
- if (date.isValid()) {
- return date.format(pattern);
- } else {
- return value;
- }
- });
- }
-
- return this.memoizedConverter(val);
- };
- };
-}
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/date_server.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/date_server.ts
deleted file mode 100644
index fa6bf8b261479..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/date_server.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { memoize, noop } from 'lodash';
-import moment from 'moment-timezone';
-import {
- FieldFormat,
- KBN_FIELD_TYPES,
- TextContextTypeConvert,
-} from '../../../../../../plugins/data/common/';
-
-export function createDateOnServerFormat() {
- return class DateFormat extends FieldFormat {
- static id = 'date';
- static title = 'Date';
- static fieldType = KBN_FIELD_TYPES.DATE;
-
- private getConfig: Function;
- private memoizedConverter: Function = noop;
- private memoizedPattern: string = '';
- private timeZone: string = '';
-
- constructor(params: Record, getConfig: Function) {
- super(params);
-
- this.getConfig = getConfig;
- this.memoizedConverter = memoize((val: any) => {
- if (val == null) {
- return '-';
- }
-
- /* On the server, importing moment returns a new instance. Unlike on
- * the client side, it doesn't have the dateFormat:tz configuration
- * baked in.
- * We need to set the timezone manually here. The date is taken in as
- * UTC and converted into the desired timezone. */
- let date;
- if (this.timeZone === 'Browser') {
- // Assume a warning has been logged this can be unpredictable. It
- // would be too verbose to log anything here.
- date = moment.utc(val);
- } else {
- date = moment.utc(val).tz(this.timeZone);
- }
-
- if (date.isValid()) {
- return date.format(this.memoizedPattern);
- } else {
- return val;
- }
- });
- }
-
- getParamDefaults() {
- return {
- pattern: this.getConfig('dateFormat'),
- timezone: this.getConfig('dateFormat:tz'),
- };
- }
-
- textConvert: TextContextTypeConvert = val => {
- // don't give away our ref to converter so we can hot-swap when config changes
- const pattern = this.param('pattern');
- const timezone = this.param('timezone');
-
- const timezoneChanged = this.timeZone !== timezone;
- const datePatternChanged = this.memoizedPattern !== pattern;
- if (timezoneChanged || datePatternChanged) {
- this.timeZone = timezone;
- this.memoizedPattern = pattern;
- }
-
- return this.memoizedConverter(val);
- };
- };
-}
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/source.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/source.ts
deleted file mode 100644
index 4d73203696bcd..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/source.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { template, escape, keys } from 'lodash';
-// @ts-ignore
-import { noWhiteSpace } from '../../utils/no_white_space';
-// @ts-ignore
-import { shortenDottedString } from '../../utils/shorten_dotted_string';
-import {
- FieldFormat,
- KBN_FIELD_TYPES,
- TextContextTypeConvert,
- HtmlContextTypeConvert,
-} from '../../../../../../plugins/data/common/';
-
-const templateHtml = `
-
- <% defPairs.forEach(function (def) { %>
- - <%- def[0] %>:
- - <%= def[1] %>
- <%= ' ' %>
- <% }); %>
-
`;
-const doTemplate = template(noWhiteSpace(templateHtml));
-
-export function createSourceFormat() {
- class SourceFormat extends FieldFormat {
- static id = '_source';
- static title = '_source';
- static fieldType = KBN_FIELD_TYPES._SOURCE;
-
- private getConfig: Function;
-
- constructor(params: Record, getConfig: Function) {
- super(params);
-
- this.getConfig = getConfig;
- }
-
- textConvert: TextContextTypeConvert = value => JSON.stringify(value);
-
- htmlConvert: HtmlContextTypeConvert = (value, field, hit) => {
- if (!field) {
- const converter = this.getConverterFor('text') as Function;
-
- return escape(converter(value));
- }
-
- const highlights = (hit && hit.highlight) || {};
- const formatted = field.indexPattern.formatHit(hit);
- const highlightPairs: any[] = [];
- const sourcePairs: any[] = [];
- const isShortDots = this.getConfig('shortDots:enable');
-
- keys(formatted).forEach(key => {
- const pairs = highlights[key] ? highlightPairs : sourcePairs;
- const newField = isShortDots ? shortenDottedString(key) : key;
- const val = formatted[key];
- pairs.push([newField, val]);
- }, []);
-
- return doTemplate({ defPairs: highlightPairs.concat(sourcePairs) });
- };
- }
-
- return SourceFormat;
-}
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/string.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/string.ts
deleted file mode 100644
index c41b94cab7cf7..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/string.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { i18n } from '@kbn/i18n';
-import { asPrettyString } from '../../../../../../plugins/data/common/field_formats';
-import {
- FieldFormat,
- KBN_FIELD_TYPES,
- TextContextTypeConvert,
-} from '../../../../../../plugins/data/common/';
-// @ts-ignore
-import { shortenDottedString } from '../../utils/shorten_dotted_string';
-
-const TRANSFORM_OPTIONS = [
- {
- kind: false,
- text: i18n.translate('kbn.common.fieldFormats.string.transformOptions.none', {
- defaultMessage: '- None -',
- }),
- },
- {
- kind: 'lower',
- text: i18n.translate('kbn.common.fieldFormats.string.transformOptions.lower', {
- defaultMessage: 'Lower Case',
- }),
- },
- {
- kind: 'upper',
- text: i18n.translate('kbn.common.fieldFormats.string.transformOptions.upper', {
- defaultMessage: 'Upper Case',
- }),
- },
- {
- kind: 'title',
- text: i18n.translate('kbn.common.fieldFormats.string.transformOptions.title', {
- defaultMessage: 'Title Case',
- }),
- },
- {
- kind: 'short',
- text: i18n.translate('kbn.common.fieldFormats.string.transformOptions.short', {
- defaultMessage: 'Short Dots',
- }),
- },
- {
- kind: 'base64',
- text: i18n.translate('kbn.common.fieldFormats.string.transformOptions.base64', {
- defaultMessage: 'Base64 Decode',
- }),
- },
- {
- kind: 'urlparam',
- text: i18n.translate('kbn.common.fieldFormats.string.transformOptions.url', {
- defaultMessage: 'URL Param Decode',
- }),
- },
-];
-const DEFAULT_TRANSFORM_OPTION = false;
-
-export function createStringFormat() {
- class StringFormat extends FieldFormat {
- static id = 'string';
- static title = 'String';
- static fieldType = [
- KBN_FIELD_TYPES.NUMBER,
- KBN_FIELD_TYPES.BOOLEAN,
- KBN_FIELD_TYPES.DATE,
- KBN_FIELD_TYPES.IP,
- KBN_FIELD_TYPES.ATTACHMENT,
- KBN_FIELD_TYPES.GEO_POINT,
- KBN_FIELD_TYPES.GEO_SHAPE,
- KBN_FIELD_TYPES.STRING,
- KBN_FIELD_TYPES.MURMUR3,
- KBN_FIELD_TYPES.UNKNOWN,
- KBN_FIELD_TYPES.CONFLICT,
- ];
- static transformOptions = TRANSFORM_OPTIONS;
-
- getParamDefaults() {
- return {
- transform: DEFAULT_TRANSFORM_OPTION,
- };
- }
-
- private base64Decode(val: string) {
- try {
- return Buffer.from(val, 'base64').toString('utf8');
- } catch (e) {
- return asPrettyString(val);
- }
- }
-
- private toTitleCase(val: string) {
- return val.replace(/\w\S*/g, txt => {
- return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
- });
- }
-
- textConvert: TextContextTypeConvert = val => {
- switch (this.param('transform')) {
- case 'lower':
- return String(val).toLowerCase();
- case 'upper':
- return String(val).toUpperCase();
- case 'title':
- return this.toTitleCase(val);
- case 'short':
- return shortenDottedString(val);
- case 'base64':
- return this.base64Decode(val);
- case 'urlparam':
- return decodeURIComponent(val);
- default:
- return asPrettyString(val);
- }
- };
- }
-
- return StringFormat;
-}
diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/url.ts b/src/legacy/core_plugins/kibana/common/field_formats/types/url.ts
deleted file mode 100644
index e9eb41513d52d..0000000000000
--- a/src/legacy/core_plugins/kibana/common/field_formats/types/url.ts
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { i18n } from '@kbn/i18n';
-import { escape, memoize } from 'lodash';
-import {
- getHighlightHtml,
- FieldFormat,
- KBN_FIELD_TYPES,
- TextContextTypeConvert,
- HtmlContextTypeConvert,
-} from '../../../../../../plugins/data/common/';
-
-const templateMatchRE = /{{([\s\S]+?)}}/g;
-const whitelistUrlSchemes = ['http://', 'https://'];
-
-const URL_TYPES = [
- {
- kind: 'a',
- text: i18n.translate('kbn.common.fieldFormats.url.types.link', {
- defaultMessage: 'Link',
- }),
- },
- {
- kind: 'img',
- text: i18n.translate('kbn.common.fieldFormats.url.types.img', {
- defaultMessage: 'Image',
- }),
- },
- {
- kind: 'audio',
- text: i18n.translate('kbn.common.fieldFormats.url.types.audio', {
- defaultMessage: 'Audio',
- }),
- },
-];
-const DEFAULT_URL_TYPE = 'a';
-
-export function createUrlFormat() {
- class UrlFormat extends FieldFormat {
- static id = 'url';
- static title = 'Url';
- static fieldType = [
- KBN_FIELD_TYPES.NUMBER,
- KBN_FIELD_TYPES.BOOLEAN,
- KBN_FIELD_TYPES.DATE,
- KBN_FIELD_TYPES.IP,
- KBN_FIELD_TYPES.STRING,
- KBN_FIELD_TYPES.MURMUR3,
- KBN_FIELD_TYPES.UNKNOWN,
- KBN_FIELD_TYPES.CONFLICT,
- ];
- static urlTypes = URL_TYPES;
-
- constructor(params: Record) {
- super(params);
- this.compileTemplate = memoize(this.compileTemplate);
- }
-
- getParamDefaults() {
- return {
- type: DEFAULT_URL_TYPE,
- urlTemplate: null,
- labelTemplate: null,
- width: null,
- height: null,
- };
- }
-
- private formatLabel(value: string, url?: string): string {
- const template = this.param('labelTemplate');
- if (url == null) url = this.formatUrl(value);
- if (!template) return url;
-
- return this.compileTemplate(template)({
- value,
- url,
- });
- }
-
- private formatUrl(value: string): string {
- const template = this.param('urlTemplate');
- if (!template) return value;
-
- return this.compileTemplate(template)({
- value: encodeURIComponent(value),
- rawValue: value,
- });
- }
-
- private compileTemplate(template: string): Function {
- // trim all the odd bits, the variable names
- const parts = template.split(templateMatchRE).map((part, i) => (i % 2 ? part.trim() : part));
-
- return function(locals: Record): string {
- // replace all the odd bits with their local var
- let output = '';
- let i = -1;
- while (++i < parts.length) {
- if (i % 2) {
- if (locals.hasOwnProperty(parts[i])) {
- const local = locals[parts[i]];
- output += local == null ? '' : local;
- }
- } else {
- output += parts[i];
- }
- }
-
- return output;
- };
- }
-
- private generateImgHtml(url: string, imageLabel: string): string {
- const isValidWidth = !isNaN(parseInt(this.param('width'), 10));
- const isValidHeight = !isNaN(parseInt(this.param('height'), 10));
- const maxWidth = isValidWidth ? `${this.param('width')}px` : 'none';
- const maxHeight = isValidHeight ? `${this.param('height')}px` : 'none';
-
- return ``;
- }
-
- textConvert: TextContextTypeConvert = value => this.formatLabel(value);
-
- htmlConvert: HtmlContextTypeConvert = (rawValue, field, hit, parsedUrl) => {
- const url = escape(this.formatUrl(rawValue));
- const label = escape(this.formatLabel(rawValue, url));
-
- switch (this.param('type')) {
- case 'audio':
- return `