diff --git a/src/platform/packages/shared/controls/controls-schemas/src/control_schema.ts b/src/platform/packages/shared/controls/controls-schemas/src/control_schema.ts index 566eb02e9264f..1afb8d7704086 100644 --- a/src/platform/packages/shared/controls/controls-schemas/src/control_schema.ts +++ b/src/platform/packages/shared/controls/controls-schemas/src/control_schema.ts @@ -12,24 +12,32 @@ import { DEFAULT_DATA_CONTROL_STATE } from '@kbn/controls-constants'; export const controlTitleSchema = schema.object({ title: schema.maybe( - schema.string({ meta: { description: 'A human-readable title for the control' } }) + schema.string({ meta: { description: 'A human-readable title for the control.' } }) ), }); export const dataControlSchema = schema.object({ ...controlTitleSchema.getPropSchemas(), data_view_id: schema.string({ - meta: { description: 'The ID of the data view that the control is tied to' }, // this will generate a reference + meta: { description: 'The ID of the data view that provides field options for this control.' }, // this will generate a reference minLength: 1, }), field_name: schema.string({ - meta: { description: 'The name of the field in the data view that the control is tied to' }, + meta: { description: 'The name of the field in the data view that this control filters on.' }, minLength: 1, }), use_global_filters: schema.boolean({ defaultValue: DEFAULT_DATA_CONTROL_STATE.use_global_filters, + meta: { + description: + "When `true`, the control's available options are narrowed by the page's active filters. Defaults to `true`.", + }, }), ignore_validations: schema.boolean({ defaultValue: DEFAULT_DATA_CONTROL_STATE.ignore_validations, + meta: { + description: + 'When `true`, the control skips selection validation and does not report which selections are responsible for returning zero results. Defaults to `false`.', + }, }), }); diff --git a/src/platform/packages/shared/controls/controls-schemas/src/controls_group_schema.ts b/src/platform/packages/shared/controls/controls-schemas/src/controls_group_schema.ts index 76c7b3233a51a..ab746b63e12af 100644 --- a/src/platform/packages/shared/controls/controls-schemas/src/controls_group_schema.ts +++ b/src/platform/packages/shared/controls/controls-schemas/src/controls_group_schema.ts @@ -30,7 +30,9 @@ export const controlWidthSchema = schema.oneOf( ], { defaultValue: DEFAULT_PINNED_CONTROL_STATE.width as typeof CONTROL_WIDTH_MEDIUM, - meta: { description: 'Minimum width of the control panel in the control group.' }, + meta: { + description: 'Minimum width of the control panel.', + }, } ); @@ -39,7 +41,10 @@ export const pinnedControlSchema = schema.object({ width: controlWidthSchema, grow: schema.boolean({ defaultValue: DEFAULT_PINNED_CONTROL_STATE.grow, - meta: { description: 'Expand width of the control panel to fit available space.' }, + meta: { + description: + 'When `true`, the control expands to fill any available horizontal space. Defaults to `false`.', + }, }), }); @@ -61,6 +66,8 @@ export const getControlsGroupSchema = () => { meta: { id: 'kbn-controls-schemas-controls-group-schema-esql-control', title: ESQL_CONTROL, + description: + 'An ES|QL variable control whose selected value is injected into ES|QL visualizations using the `?variable_name` syntax. Options can come from a fixed list or an ES|QL query. Define the options source in `config`.', }, } ), @@ -74,6 +81,8 @@ export const getControlsGroupSchema = () => { meta: { id: 'kbn-controls-schemas-controls-group-schema-options-list-control', title: OPTIONS_LIST_CONTROL, + description: + 'A dropdown control that filters data by selecting field values from a data view. Define the data view, field, and selection settings in `config`.', }, } ), @@ -87,6 +96,8 @@ export const getControlsGroupSchema = () => { meta: { id: 'kbn-controls-schemas-controls-group-schema-range-slider-control', title: RANGE_SLIDER_CONTROL, + description: + 'A slider control that filters data by selecting a numeric range for the configured field. Define the data view, field, and selection settings in `config`.', }, } ), @@ -100,6 +111,8 @@ export const getControlsGroupSchema = () => { meta: { id: 'kbn-controls-schemas-controls-group-schema-time-slider-control', title: TIME_SLIDER_CONTROL, + description: + 'A control panel that filters a time field to a selected sub-range of the global time range. Define the start and end positions in `config` as fractions of the global range (0 to 1).', }, } ), diff --git a/src/platform/packages/shared/controls/controls-schemas/src/options_list_schema.ts b/src/platform/packages/shared/controls/controls-schemas/src/options_list_schema.ts index 33e11d1691fd9..fca8af23fd7a1 100644 --- a/src/platform/packages/shared/controls/controls-schemas/src/options_list_schema.ts +++ b/src/platform/packages/shared/controls/controls-schemas/src/options_list_schema.ts @@ -18,27 +18,83 @@ import { controlTitleSchema, dataControlSchema } from './control_schema'; const SELECTIONS_MAX = 10000; export const optionsListDisplaySettingsSchema = schema.object({ - placeholder: schema.maybe(schema.string()), - hide_action_bar: schema.maybe(schema.boolean()), - hide_exclude: schema.maybe(schema.boolean()), - hide_exists: schema.maybe(schema.boolean()), - hide_sort: schema.maybe(schema.boolean()), + placeholder: schema.maybe( + schema.string({ + meta: { + description: 'Placeholder text displayed in the control input when no option is selected.', + }, + }) + ), + hide_action_bar: schema.maybe( + schema.boolean({ + meta: { + description: + 'When `true`, the search bar, sorting options, and select all toggle are hidden from the control.', + }, + }) + ), + hide_exclude: schema.maybe( + schema.boolean({ + meta: { + description: 'When `true`, the exclude mode toggle is hidden from the control.', + }, + }) + ), + hide_exists: schema.maybe( + schema.boolean({ + meta: { + description: 'When `true`, the exists filter option is hidden from the control.', + }, + }) + ), + hide_sort: schema.maybe( + schema.boolean({ + meta: { + description: 'When `true`, the sort selector is hidden from the control.', + }, + }) + ), }); export const optionsListSearchTechniqueSchema = schema.oneOf( [schema.literal('prefix'), schema.literal('wildcard'), schema.literal('exact')], - { defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.search_technique } + { + defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.search_technique, + meta: { + description: + 'The matching technique used when searching available options. `prefix` matches values starting with the search term, `wildcard` matches values containing the search term, and `exact` requires a complete match. Only applies to string and IP fields. Defaults to `wildcard`.', + }, + } ); export const optionsListSortSchema = schema.object( { - by: schema.oneOf([schema.literal('_count'), schema.literal('_key')]), - direction: schema.oneOf([schema.literal('asc'), schema.literal('desc')]), + by: schema.oneOf([schema.literal('_count'), schema.literal('_key')], { + meta: { + description: + 'The field used to sort the available options list. `_count` sorts by document count and `_key` sorts alphabetically by option value.', + }, + }), + direction: schema.oneOf([schema.literal('asc'), schema.literal('desc')], { + meta: { + description: 'The sort direction. `asc` sorts ascending and `desc` sorts descending.', + }, + }), }, - { defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.sort } + { + defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.sort, + meta: { + description: + 'Defines how the available options are sorted in the control popover. Defaults to `{ by: "_count", direction: "desc" }`.', + }, + } ); -export const optionsListSelectionSchema = schema.oneOf([schema.string(), schema.number()]); +export const optionsListSelectionSchema = schema.oneOf([schema.string(), schema.number()], { + meta: { + description: 'A selected option value. Accepts a string or a number.', + }, +}); const optionsListControlBaseParameters = schema.object({ display_settings: schema.maybe(optionsListDisplaySettingsSchema), @@ -47,35 +103,82 @@ const optionsListControlBaseParameters = schema.object({ export const optionsListDSLControlSchema = schema.object({ ...optionsListControlBaseParameters.getPropSchemas(), ...dataControlSchema.getPropSchemas(), - exclude: schema.boolean({ defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.exclude }), + exclude: schema.boolean({ + defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.exclude, + meta: { + description: + 'When `true`, the control filters to documents that do NOT match the selected options. Defaults to `false`.', + }, + }), exists_selected: schema.boolean({ defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.exists_selected, + meta: { + description: + "When `true`, the control filters to documents where the field exists, regardless of the field's value. Defaults to `false`.", + }, }), run_past_timeout: schema.boolean({ defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.run_past_timeout, + meta: { + description: + 'When `true`, the options list query continues running even if it exceeds the configured timeout threshold. Defaults to `false`.', + }, }), search_technique: optionsListSearchTechniqueSchema, selected_options: schema.arrayOf(optionsListSelectionSchema, { defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.selected_options, maxSize: SELECTIONS_MAX, + meta: { + description: 'The list of currently selected option values.', + }, + }), + single_select: schema.boolean({ + defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.single_select, + meta: { + description: + 'When `true`, only one option can be selected at a time. Selecting a new option deselects any previously selected option. Defaults to `false`.', + }, }), - single_select: schema.boolean({ defaultValue: DEFAULT_DSL_OPTIONS_LIST_STATE.single_select }), sort: optionsListSortSchema, }); const baseEsqlControl = { ...controlTitleSchema.getPropSchemas(), ...optionsListControlBaseParameters.getPropSchemas(), - selected_options: schema.arrayOf(schema.string(), { maxSize: SELECTIONS_MAX }), - single_select: schema.boolean({ defaultValue: DEFAULT_ESQL_OPTIONS_LIST_STATE.single_select }), - variable_name: schema.string(), - variable_type: schema.oneOf([ - schema.literal('fields'), - schema.literal('values'), - schema.literal('functions'), - schema.literal('time_literal'), - schema.literal('multi_values'), - ]), + selected_options: schema.arrayOf(schema.string(), { + maxSize: SELECTIONS_MAX, + meta: { + description: 'The list of currently selected option values.', + }, + }), + single_select: schema.boolean({ + defaultValue: DEFAULT_ESQL_OPTIONS_LIST_STATE.single_select, + meta: { + description: + 'When `true`, only one option can be selected at a time. Selecting a new option deselects any previously selected option. Defaults to `true`.', + }, + }), + variable_name: schema.string({ + meta: { + description: + 'The name of the ES|QL variable that this control populates. The variable is referenced in ES|QL queries using the `?variable_name` syntax.', + }, + }), + variable_type: schema.oneOf( + [ + schema.literal('fields'), + schema.literal('values'), + schema.literal('functions'), + schema.literal('time_literal'), + schema.literal('multi_values'), + ], + { + meta: { + description: + 'The ES|QL variable type that determines how the selected value is substituted into the query. Accepts `fields`, `values`, `functions`, `time_literal`, or `multi_values`.', + }, + } + ), }; export const optionsListESQLControlSchema = schema.discriminatedUnion('control_type', [ @@ -85,11 +188,17 @@ export const optionsListESQLControlSchema = schema.discriminatedUnion('control_t control_type: schema.literal('STATIC_VALUES'), available_options: schema.arrayOf(schema.string(), { maxSize: MAX_OPTIONS_LIST_REQUEST_SIZE, + meta: { + description: 'A fixed list of option strings displayed in the control.', + }, }), }, { meta: { id: 'kbn-controls-schemas-options-list-esql-control-schema-static-values', + title: 'STATIC_VALUES', + description: + 'An ES|QL variable control with a fixed list of selectable options defined directly in `available_options`.', }, } ), @@ -97,11 +206,19 @@ export const optionsListESQLControlSchema = schema.discriminatedUnion('control_t { ...baseEsqlControl, control_type: schema.literal('VALUES_FROM_QUERY'), - esql_query: schema.string(), + esql_query: schema.string({ + meta: { + description: + 'An ES|QL query whose results populate the list of available options in the control popover.', + }, + }), }, { meta: { id: 'kbn-controls-schemas-options-list-esql-control-schema-values-from-query', + title: 'VALUES_FROM_QUERY', + description: + 'An ES|QL variable control whose selectable options are dynamically retrieved by running an ES|QL query.', }, } ), diff --git a/src/platform/packages/shared/controls/controls-schemas/src/range_slider_schema.ts b/src/platform/packages/shared/controls/controls-schemas/src/range_slider_schema.ts index d57db1913cc24..c96069972eb2e 100644 --- a/src/platform/packages/shared/controls/controls-schemas/src/range_slider_schema.ts +++ b/src/platform/packages/shared/controls/controls-schemas/src/range_slider_schema.ts @@ -11,10 +11,23 @@ import { schema } from '@kbn/config-schema'; import { DEFAULT_RANGE_SLIDER_STATE } from '@kbn/controls-constants'; import { dataControlSchema } from './control_schema'; -export const rangeValueSchema = schema.arrayOf(schema.string(), { minSize: 2, maxSize: 2 }); +export const rangeValueSchema = schema.arrayOf(schema.string(), { + minSize: 2, + maxSize: 2, + meta: { + description: + 'The selected range as a two-element array of strings representing the lower and upper bound values, for example `["10", "50"]`.', + }, +}); export const rangeSliderControlSchema = schema.object({ ...dataControlSchema.getPropSchemas(), value: schema.maybe(rangeValueSchema), - step: schema.number({ defaultValue: DEFAULT_RANGE_SLIDER_STATE.step, min: 0 }), + step: schema.number({ + defaultValue: DEFAULT_RANGE_SLIDER_STATE.step, + min: 0, + meta: { + description: 'The step size between selectable range values.', + }, + }), }); diff --git a/src/platform/packages/shared/controls/controls-schemas/src/time_slider_schema.ts b/src/platform/packages/shared/controls/controls-schemas/src/time_slider_schema.ts index 4972b21bc7dc7..7744d916d3b42 100644 --- a/src/platform/packages/shared/controls/controls-schemas/src/time_slider_schema.ts +++ b/src/platform/packages/shared/controls/controls-schemas/src/time_slider_schema.ts @@ -15,11 +15,25 @@ export const timeSliderControlSchema = schema.object({ defaultValue: DEFAULT_TIME_SLIDER_STATE.start_percentage_of_time_range, min: 0, max: 1, + meta: { + description: + 'The start of the selected time window expressed as a fraction of the global time range, where `0` is the beginning and `1` is the end of the range.', + }, }), end_percentage_of_time_range: schema.number({ defaultValue: DEFAULT_TIME_SLIDER_STATE.end_percentage_of_time_range, min: 0, max: 1, + meta: { + description: + 'The end of the selected time window expressed as a fraction of the global time range, where `0` is the beginning and `1` is the end of the range.', + }, + }), + is_anchored: schema.boolean({ + defaultValue: DEFAULT_TIME_SLIDER_STATE.is_anchored, + meta: { + description: + 'When `true`, the start of the time window is fixed at the beginning of the global time range. Only the end of the window can be adjusted. Defaults to `false`.', + }, }), - is_anchored: schema.boolean({ defaultValue: DEFAULT_TIME_SLIDER_STATE.is_anchored }), });