elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.57k stars 8.09k forks source link

[Research][Embeddable Variables] Initial Project Description #134706

Open ThomThomson opened 2 years ago

ThomThomson commented 2 years ago

Describe the project

There are a few use cases - for example https://github.com/elastic/kibana/issues/134592 and https://github.com/elastic/kibana/issues/134591 which require Embeddable Containers to pass input to their children which overrides the child's input. We will need to provide a mechanism for this type of inheritance. This mechanism should act as a standardized system for any future / existing requirements that involve a container storing state which should override one or more configuration options on its children.

In general, a generic container should not store state for any specific type of embeddable without a system in place to handle it generically. This issue is an initial exploration of how something like that could be built.

Rough Diagram

Screen Shot 2022-06-21 at 5 03 28 PM

Concepts

Variable Controls

A new and totally separate type of Control should be built that interacts with variables instead of data. Creating / editing these controls would be a separate experience from the data controls, but they should exist in the same bar and look similar.

Each variable type will come with its own variable control embeddable, factory, and its own inline editor the same as controls do. UX-wise, when creating a variable control the user will be prompted with a list of types that they need to choose from.

Variable controls store all of their configuration with the Control Group Input, including initial / default selections. These controls publish their selections as output to the Control Group which in turn publishes all of its Variables into its output along with its filters.

A container like the Dashboard Container could subscribe to these output changes, and update its Variable Store accordingly.

Variable Store

Any embeddable container could implement a new interface IVariableStore which would be used to store variables.

The IVariableStore interface would look something like

interface Variable {
  type: string;
  id: string;
  value: string;
}

export interface VariableStore {
  byId: { [id: string]: Variable };
  byType: { [type: string]: Variable[] };
}

export interface IVariableStore {
  getCurrentStore: () => 
  getVariablesByType: (type: string) => Variable[];
  getVariableById: (id: string) => Variable;
  addVariable: (variable: Variable) => void;
}

Note The variable store is meant to be ephemeral. It should not be stored in a saved object. The variable store is only an intermediary, and a communication method for inheritance. Any variable values which are saved should be saved in the Control Group to allow for extract / inject / migrations.

Variable Slots

Any embeddable could implement a new interface IVariableSlotEmbeddable which would provide methods for getting all variable slots. These can be hardcoded, or determined by the embeddables current state. Each Variable slot would follow an interface similar to:

{
  type: string // used to determine which type of variable can be applied here.
  key: string // a key of this embeddable's input type, it determines which key this variable would override
  displayName: string // a title to be shown to the user when selecting a value for this variable.
  variableId: string; // The user-defined variable that should go in this slot.
}

Variable Inheritance

If a container extends IVariableStoreEmbeddable it can pass the appropriate variables down to the child during the getInputForChild method. First the container would check if the current embeddable extends IVariableSlotEmbeddable, and if it does the container would:

Loop through the child embeddable's variable slots
  if that slot is assigned (has a variableId)
    If the variable has a value assigned to that id use the value
    Else fallback to the child's default value.
  add the appropriate value to the input to pass down to the child.

Variable Assign Action

If the embeddable extends IVariableSlotEmbeddable, and its parent extends IVariableStoreEmbeddable a new action should be compatible which opens a flyout that allows users to select variables by their ID / display name for each slot that the embeddable features.

elasticmachine commented 2 years ago

Pinging @elastic/kibana-app-services (Team:AppServicesSv)

elasticmachine commented 2 years ago

Pinging @elastic/kibana-presentation (Team:Presentation)

teresaalvarezsoler commented 1 year ago

Related: https://github.com/elastic/kibana/issues/160001