diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/constant_keyword_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/constant_keyword_type.tsx
new file mode 100644
index 0000000000000..4c02171d49eec
--- /dev/null
+++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/constant_keyword_type.tsx
@@ -0,0 +1,82 @@
+/*
+ * 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 { i18n } from '@kbn/i18n';
+
+import { documentationService } from '../../../../../../services/documentation';
+import { UseField, Field, JsonEditorField } from '../../../../shared_imports';
+import { getFieldConfig } from '../../../../lib';
+import { NormalizedField } from '../../../../types';
+import { AdvancedParametersSection, EditFieldFormRow, BasicParametersSection } from '../edit_field';
+
+interface Props {
+ field: NormalizedField;
+}
+
+export const ConstantKeywordType: FunctionComponent = ({ field }) => {
+ return (
+ <>
+
+ {/* Value field */}
+
+
+
+
+
+
+ {/* Meta field */}
+
+
+
+
+ >
+ );
+};
diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts
index d84d9c6ea40cf..0cf921f66451b 100644
--- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts
+++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts
@@ -28,6 +28,7 @@ import { ObjectType } from './object_type';
import { OtherType } from './other_type';
import { NestedType } from './nested_type';
import { JoinType } from './join_type';
+import { ConstantKeywordType } from './constant_keyword_type';
import { RankFeatureType } from './rank_feature_type';
import { WildcardType } from './wildcard_type';
@@ -54,6 +55,7 @@ const typeToParametersFormMap: { [key in DataType]?: ComponentType } = {
other: OtherType,
nested: NestedType,
join: JoinType,
+ constant_keyword: ConstantKeywordType,
rank_feature: RankFeatureType,
wildcard: WildcardType,
};
diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx
index a8844c7a9b270..18d9c637bd45b 100644
--- a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx
+++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx
@@ -71,6 +71,26 @@ export const TYPE_DEFINITION: { [key in DataType]: DataTypeDefinition } = {
),
},
+ constant_keyword: {
+ value: 'constant_keyword',
+ label: i18n.translate('xpack.idxMgmt.mappingsEditor.dataType.constantKeywordDescription', {
+ defaultMessage: 'Constant keyword',
+ }),
+ documentation: {
+ main: '/keyword.html#constant-keyword-field-type',
+ },
+ description: () => (
+
+ {'keyword'},
+ }}
+ />
+
+ ),
+ },
numeric: {
value: 'numeric',
label: i18n.translate('xpack.idxMgmt.mappingsEditor.dataType.numericDescription', {
@@ -822,6 +842,7 @@ export const MAIN_TYPES: MainType[] = [
'binary',
'boolean',
'completion',
+ 'constant_keyword',
'date',
'date_nanos',
'dense_vector',
diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx
index f2148f1f657a6..fd17dc1b8fd1e 100644
--- a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx
+++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx
@@ -29,7 +29,7 @@ import { INDEX_DEFAULT } from './default_values';
import { TYPE_DEFINITION } from './data_types_definition';
const { toInt } = fieldFormatters;
-const { emptyField, containsCharsField, numberGreaterThanField } = fieldValidators;
+const { emptyField, containsCharsField, numberGreaterThanField, isJsonField } = fieldValidators;
const commonErrorMessages = {
smallerThanZero: i18n.translate(
@@ -404,6 +404,88 @@ export const PARAMETERS_DEFINITION: { [key in ParameterName]: ParameterDefinitio
},
schema: t.string,
},
+ value: {
+ fieldConfig: {
+ defaultValue: '',
+ type: FIELD_TYPES.TEXT,
+ label: i18n.translate('xpack.idxMgmt.mappingsEditor.parameters.valueLabel', {
+ defaultMessage: 'Value',
+ }),
+ },
+ schema: t.string,
+ },
+ meta: {
+ fieldConfig: {
+ defaultValue: '',
+ label: i18n.translate('xpack.idxMgmt.mappingsEditor.parameters.metaLabel', {
+ defaultMessage: 'Metadata',
+ }),
+ helpText: (
+ {JSON.stringify({ arbitrary_key: 'anything_goes' })},
+ }}
+ />
+ ),
+ validations: [
+ {
+ validator: isJsonField(
+ i18n.translate('xpack.idxMgmt.mappingsEditor.parameters.metaFieldEditorJsonError', {
+ defaultMessage: 'Invalid JSON.',
+ }),
+ { allowEmptyString: true }
+ ),
+ },
+ {
+ validator: ({ value }: ValidationFuncArg) => {
+ if (typeof value !== 'string' || value.trim() === '') {
+ return;
+ }
+
+ const json = JSON.parse(value);
+ const valuesAreNotString = Object.values(json).some((v) => typeof v !== 'string');
+
+ if (Array.isArray(json)) {
+ return {
+ message: i18n.translate(
+ 'xpack.idxMgmt.mappingsEditor.parameters.metaFieldEditorArraysNotAllowedError',
+ {
+ defaultMessage: 'Arrays are not allowed.',
+ }
+ ),
+ };
+ } else if (valuesAreNotString) {
+ return {
+ message: i18n.translate(
+ 'xpack.idxMgmt.mappingsEditor.parameters.metaFieldEditorOnlyStringValuesAllowedError',
+ {
+ defaultMessage: 'Values must be a string.',
+ }
+ ),
+ };
+ }
+ },
+ },
+ ],
+ deserializer: (value: any) => {
+ if (value === '') {
+ return value;
+ }
+ return JSON.stringify(value, null, 2);
+ },
+ serializer: (value: string) => {
+ const parsed = JSON.parse(value);
+ // If an empty object was passed, strip out this value entirely.
+ if (!Object.keys(parsed).length) {
+ return undefined;
+ }
+ return parsed;
+ },
+ },
+ schema: t.any,
+ },
max_input_length: {
fieldConfig: {
defaultValue: 50,
diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts
index fd0e4ed32bfe8..c2a44152ae1ee 100644
--- a/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts
+++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts
@@ -59,6 +59,7 @@ export type MainType =
| 'geo_point'
| 'geo_shape'
| 'token_count'
+ | 'constant_keyword'
| 'wildcard'
/**
* 'other' is a special type that only exists inside of MappingsEditor as a placeholder
@@ -146,7 +147,9 @@ export type ParameterName =
| 'dims'
| 'depth_limit'
| 'relations'
- | 'max_shingle_size';
+ | 'max_shingle_size'
+ | 'value'
+ | 'meta';
export interface Parameter {
fieldConfig: FieldConfig;
diff --git a/x-pack/plugins/index_management/public/application/services/documentation.ts b/x-pack/plugins/index_management/public/application/services/documentation.ts
index afc9c76f1afbe..c52b958d94ae1 100644
--- a/x-pack/plugins/index_management/public/application/services/documentation.ts
+++ b/x-pack/plugins/index_management/public/application/services/documentation.ts
@@ -123,6 +123,10 @@ class DocumentationService {
return `${this.esDocsBase}/ignore-malformed.html`;
}
+ public getMetaLink() {
+ return `${this.esDocsBase}/mapping-field-meta.html`;
+ }
+
public getFormatLink() {
return `${this.esDocsBase}/mapping-date-format.html`;
}