diff --git a/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.html b/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.html
index 25b713bd7fd30e..5a8735d7b3ea80 100644
--- a/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.html
+++ b/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.html
@@ -1,7 +1,32 @@
-
- Docs: {{sampleDocs}}
+
-
Create an index pattern
+
diff --git a/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.js b/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.js
index 240e97a036a5ea..be7a220636edf4 100644
--- a/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.js
+++ b/src/plugins/kibana/public/settings/sections/indices/add_data_steps/pattern_review_step.js
@@ -1,5 +1,65 @@
-var modules = require('ui/modules');
-var template = require('plugins/kibana/settings/sections/indices/add_data_steps/pattern_review_step.html');
+const modules = require('ui/modules');
+const template = require('plugins/kibana/settings/sections/indices/add_data_steps/pattern_review_step.html');
+const _ = require('lodash');
+const editFieldTypeHTML = require('plugins/kibana/settings/sections/indices/partials/_edit_field_type.html');
+
+const testData = {
+ message: '11/24/2015 ip=1.1.1.1 bytes=1234',
+ clientip: '1.1.1.1',
+ bytes: 1234,
+ geoip: {
+ lat: 37.3894,
+ lon: 122.0819
+ },
+ location: {
+ lat: 37.3894,
+ lon: 122.0819
+ },
+ '@timestamp': '2015-11-24T00:00:00.000Z',
+ otherdate: '2015-11-24T00:00:00.000Z',
+ codes: [1, 2, 3, 4]
+};
+
+const testPipeline = [
+ {
+ grok: {
+ match_field: 'message',
+ match_pattern: 'foo'
+ }
+ },
+ {
+ geoip: {
+ source_field: 'ip'
+ }
+ },
+ {
+ geoip: {
+ source_field: 'ip',
+ target_field: 'location'
+ }
+ },
+ {
+ date: {
+ match_field: 'initialDate',
+ match_formats: ['dd/MM/yyyy hh:mm:ss']
+ }
+ },
+ {
+ date: {
+ match_field: 'initialDate',
+ match_formats: ['dd/MM/yyyy hh:mm:ss'],
+ target_field: 'otherdate'
+ }
+ }
+];
+
+function pickDefaultTimeFieldName(dateFields) {
+ if (_.isEmpty(dateFields)) {
+ return undefined;
+ }
+
+ return _.includes(dateFields, '@timestamp') ? '@timestamp' : dateFields[0];
+}
modules.get('apps/settings')
.directive('patternReviewStep', function () {
@@ -9,6 +69,83 @@ modules.get('apps/settings')
sampleDocs: '=',
indexPattern: '=',
pipeline: '='
+ },
+ controllerAs: 'reviewStep',
+ bindToController: true,
+ controller: function ($scope, Private) {
+ this.sampleDocs = testData;
+ this.pipeline = testPipeline;
+
+ if (_.isUndefined(this.indexPattern)) {
+ this.indexPattern = {};
+ }
+
+ const knownFieldTypes = {};
+ this.dateFields = [];
+ this.pipeline.forEach((processor) => {
+ if (processor.geoip) {
+ const field = processor.geoip.target_field || 'geoip';
+ knownFieldTypes[field] = 'geo_point';
+ }
+ else if (processor.date) {
+ const field = processor.date.target_field || '@timestamp';
+ knownFieldTypes[field] = 'date';
+ this.dateFields.push(field);
+ }
+ });
+
+ _.defaults(this.indexPattern, {
+ id: 'filebeat-*',
+ title: 'filebeat-*',
+ timeFieldName: pickDefaultTimeFieldName(this.dateFields),
+ fields: _.map(this.sampleDocs, (value, key) => {
+ let type = knownFieldTypes[key] || typeof value;
+ if (type === 'object' && _.isArray(value) && !_.isEmpty(value)) {
+ type = typeof value[0];
+ }
+ return {name: key, type: type};
+ })
+ });
+
+ this.isTimeBased = !!this.indexPattern.timeFieldName;
+
+ $scope.$watch('reviewStep.indexPattern.id', (value) => {
+ this.indexPattern.title = value;
+ });
+ $scope.$watch('reviewStep.isTimeBased', (value) => {
+ if (value) {
+ this.indexPattern.timeFieldName = pickDefaultTimeFieldName(this.dateFields);
+ }
+ else {
+ delete this.indexPattern.timeFieldName;
+ }
+ });
+ $scope.$watch('reviewStep.indexPattern.fields', (fields) => {
+ this.dateFields = _.map(_.filter(fields, {type: 'date'}), 'name');
+ }, true);
+
+ const buildRows = () => {
+ this.rows = _.map(this.indexPattern.fields, (field) => {
+ const sampleValue = this.sampleDocs[field.name];
+ return [
+ _.escape(field.name),
+ {
+ markup: editFieldTypeHTML,
+ scope: _.assign($scope.$new(), {field: field, knownFieldTypes: knownFieldTypes, buildRows: buildRows}),
+ value: field.type
+ },
+ typeof sampleValue === 'object' ? _.escape(JSON.stringify(sampleValue)) : _.escape(sampleValue)
+ ];
+ });
+ };
+
+ this.columns = [
+ {title: 'Field'},
+ {title: 'Type'},
+ {title: 'Example', sortable: false}
+ ];
+
+ buildRows();
}
};
});
diff --git a/src/plugins/kibana/public/settings/sections/indices/filebeat/directives/filebeat_wizard.html b/src/plugins/kibana/public/settings/sections/indices/filebeat/directives/filebeat_wizard.html
index 094cbeecdfe6a4..7fc03086509c51 100644
--- a/src/plugins/kibana/public/settings/sections/indices/filebeat/directives/filebeat_wizard.html
+++ b/src/plugins/kibana/public/settings/sections/indices/filebeat/directives/filebeat_wizard.html
@@ -59,7 +59,10 @@
Tail a File
Prev
- Save
+
+ Save
+
diff --git a/src/plugins/kibana/public/settings/sections/indices/partials/_edit_field_type.html b/src/plugins/kibana/public/settings/sections/indices/partials/_edit_field_type.html
new file mode 100644
index 00000000000000..b80ded8219f116
--- /dev/null
+++ b/src/plugins/kibana/public/settings/sections/indices/partials/_edit_field_type.html
@@ -0,0 +1,13 @@
+