diff --git a/x-pack/plugins/painless_lab/public/application/components/editor.tsx b/x-pack/plugins/painless_lab/public/application/components/editor.tsx index 6c4bd5da47911..53d6ffac82011 100644 --- a/x-pack/plugins/painless_lab/public/application/components/editor.tsx +++ b/x-pack/plugins/painless_lab/public/application/components/editor.tsx @@ -6,14 +6,15 @@ */ import React from 'react'; -import { PainlessLang, PainlessContext } from '@kbn/monaco'; +import { PainlessLang } from '@kbn/monaco'; import { CodeEditor } from '../../../../../../src/plugins/kibana_react/public'; +import { ExecutionContext } from '../types'; interface Props { code: string; onChange: (code: string) => void; - context: PainlessContext; + context: ExecutionContext; } export function Editor({ code, onChange, context }: Props) { diff --git a/x-pack/plugins/painless_lab/public/application/components/output_pane/context_tab.tsx b/x-pack/plugins/painless_lab/public/application/components/output_pane/context_tab.tsx index a8ee5bc90c72e..e49134cb21a97 100644 --- a/x-pack/plugins/painless_lab/public/application/components/output_pane/context_tab.tsx +++ b/x-pack/plugins/painless_lab/public/application/components/output_pane/context_tab.tsx @@ -19,11 +19,12 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { PainlessContext } from '@kbn/monaco'; import { CodeEditor } from '../../../../../../../src/plugins/kibana_react/public'; import { painlessContextOptions } from '../../constants'; import { useAppContext } from '../../context'; +import { isAdvancedContext } from '../../lib/utils'; +import { ExecutionContext } from '../../types'; export const ContextTab: FunctionComponent = () => { const { @@ -66,14 +67,14 @@ export const ContextTab: FunctionComponent = () => { updatePayload({ context: nextContext })} + onChange={(nextContext: ExecutionContext) => updatePayload({ context: nextContext })} itemLayoutAlign="top" hasDividers fullWidth /> - {['filter', 'score'].indexOf(context) !== -1 && ( + {isAdvancedContext(context) && ( { )} - {['filter', 'score'].indexOf(context) !== -1 && ( + + {isAdvancedContext(context) && ( > = [ - { - value: 'painless_test', - inputDisplay: defaultLabel, - 'data-test-subj': 'basicButtonDropdown', - dropdownDisplay: ( - <> - {defaultLabel} - -

- {i18n.translate('xpack.painlessLab.context.defaultLabel', { - defaultMessage: 'The script result will be converted to a string', - })} -

-
- - ), +import { ExecutionContext } from './types'; + +const i18nTexts: { + [key in ExecutionContext]: { + buttonLabel: string; + dropdownDescription: string; + }; +} = { + painless_test: { + buttonLabel: i18n.translate('xpack.painlessLab.contextDefaultLabel', { + defaultMessage: 'Basic', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.defaultLabel', { + defaultMessage: 'The script result will be converted to a string', + }), + }, + filter: { + buttonLabel: i18n.translate('xpack.painlessLab.contextFilterLabel', { + defaultMessage: 'Filter', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.filterLabel', { + defaultMessage: "Use the context of a filter's script query", + }), + }, + score: { + buttonLabel: i18n.translate('xpack.painlessLab.contextScoreLabel', { + defaultMessage: 'Score', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.scoreLabel', { + defaultMessage: 'Use the context of a script_score function in function_score query', + }), + }, + boolean_script_field_script_field: { + buttonLabel: i18n.translate('xpack.painlessLab.contextBooleanLabel', { + defaultMessage: 'Boolean', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.booleanLabel', { + defaultMessage: 'TODO', + }), }, - { - value: 'filter', - inputDisplay: filterLabel, - 'data-test-subj': 'filterButtonDropdown', - dropdownDisplay: ( - <> - {filterLabel} - -

- {i18n.translate('xpack.painlessLab.context.filterLabel', { - defaultMessage: "Use the context of a filter's script query", - })} -

-
- - ), + date_script_field: { + buttonLabel: i18n.translate('xpack.painlessLab.contextDateLabel', { + defaultMessage: 'Date', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.dateLabel', { + defaultMessage: 'TODO', + }), }, - { - value: 'score', - inputDisplay: scoreLabel, - 'data-test-subj': 'scoreButtonDropdown', - dropdownDisplay: ( - <> - {scoreLabel} - -

- {i18n.translate('xpack.painlessLab.context.scoreLabel', { - defaultMessage: 'Use the context of a script_score function in function_score query', - })} -

-
- - ), + double_script_field_script_field: { + buttonLabel: i18n.translate('xpack.painlessLab.contextDoubleLabel', { + defaultMessage: 'Double', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.doubleLabel', { + defaultMessage: 'TODO', + }), }, + ip_script_field_script_field: { + buttonLabel: i18n.translate('xpack.painlessLab.contextIpLabel', { + defaultMessage: 'IP', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.ipLabel', { + defaultMessage: 'TODO', + }), + }, + long_script_field_script_field: { + buttonLabel: i18n.translate('xpack.painlessLab.contextLongLabel', { + defaultMessage: 'Long', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.longLabel', { + defaultMessage: 'TODO', + }), + }, + string_script_field_script_field: { + buttonLabel: i18n.translate('xpack.painlessLab.contextStringLabel', { + defaultMessage: 'String', + }), + dropdownDescription: i18n.translate('xpack.painlessLab.context.stringLabel', { + defaultMessage: 'TODO', + }), + }, +}; + +const painlessContexts: ExecutionContext[] = [ + 'painless_test', + 'filter', + 'score', + 'boolean_script_field_script_field', + 'date_script_field', + 'double_script_field_script_field', + 'ip_script_field_script_field', + 'long_script_field_script_field', + 'string_script_field_script_field', ]; +export const painlessContextOptions: Array< + EuiSuperSelectOption +> = painlessContexts.map((context) => ({ + value: context, + inputDisplay: i18nTexts[context].buttonLabel, + 'data-test-subj': `${context}ButtonDropdown`, + dropdownDisplay: ( + <> + {i18nTexts[context].buttonLabel} + +

{i18nTexts[context].dropdownDescription}

+
+ + ), +})); + // Render a smiley face as an example. export const exampleScript = `boolean isInCircle(def posX, def posY, def circleX, def circleY, def radius) { double distanceFromCircleCenter = Math.sqrt(Math.pow(circleX - posX, 2) + Math.pow(circleY - posY, 2)); diff --git a/x-pack/plugins/painless_lab/public/application/lib/format.ts b/x-pack/plugins/painless_lab/public/application/lib/format.ts index 65e2ba40dd0ff..3b4211272a859 100644 --- a/x-pack/plugins/painless_lab/public/application/lib/format.ts +++ b/x-pack/plugins/painless_lab/public/application/lib/format.ts @@ -6,6 +6,7 @@ */ import { Response, ExecutionError, PayloadFormat, Payload } from '../types'; +import { isAdvancedContext } from './utils'; function prettifyPayload(payload = '', indentationLevel = 0) { const indentation = new Array(indentationLevel + 1).join(' '); @@ -20,8 +21,6 @@ export function formatRequestPayload( { code, context, parameters, index, document, query }: Partial, format: PayloadFormat = PayloadFormat.UGLY ): string { - const isAdvancedContext = context === 'filter' || context === 'score'; - let formattedCode: string | undefined; let formattedParameters: string | undefined; let formattedContext: string | undefined; @@ -55,7 +54,7 @@ export function formatRequestPayload( : `` } }${ - isAdvancedContext + isAdvancedContext(context) ? `, "context": "${formattedContext}", "context_setup": { diff --git a/x-pack/plugins/painless_lab/public/application/lib/utils.ts b/x-pack/plugins/painless_lab/public/application/lib/utils.ts new file mode 100644 index 0000000000000..3c201a547276a --- /dev/null +++ b/x-pack/plugins/painless_lab/public/application/lib/utils.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ExecutionContext } from '../types'; + +/* + * Excludes the "painless_test" context + * This util is used to determine whether or not to show + * the "Index" and "Document" fields under the "Context" tab + */ +const advancedContextTypes: ExecutionContext[] = [ + 'filter', + 'score', + 'boolean_script_field_script_field', + 'date_script_field', + 'double_script_field_script_field', + 'ip_script_field_script_field', + 'long_script_field_script_field', + 'string_script_field_script_field', +]; + +export const isAdvancedContext = (context?: ExecutionContext) => + Boolean(context && advancedContextTypes.indexOf(context) !== -1); diff --git a/x-pack/plugins/painless_lab/public/application/types.ts b/x-pack/plugins/painless_lab/public/application/types.ts index 8b8f9ac60e600..f0cb619fda7e8 100644 --- a/x-pack/plugins/painless_lab/public/application/types.ts +++ b/x-pack/plugins/painless_lab/public/application/types.ts @@ -12,8 +12,10 @@ export interface Store { validation: Validation; } +export type ExecutionContext = Exclude; + export interface Payload { - context: PainlessContext; + context: ExecutionContext; code: string; parameters: string; index: string; @@ -28,9 +30,6 @@ export interface Validation { }; } -// TODO: This should be an enumerated list -export type Context = string; - export enum PayloadFormat { UGLY = 'ugly', PRETTY = 'pretty',