-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into observability-remove-timeline-deps
- Loading branch information
Showing
16 changed files
with
281 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
src/plugins/controls/public/control_group/control_group_renderer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* 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 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import uuid from 'uuid'; | ||
import useLifecycles from 'react-use/lib/useLifecycles'; | ||
import React, { useEffect, useMemo, useRef, useState } from 'react'; | ||
|
||
import { IEmbeddable } from '@kbn/embeddable-plugin/public'; | ||
|
||
import { pluginServices } from '../services'; | ||
import { getDefaultControlGroupInput } from '../../common'; | ||
import { ControlGroupInput, ControlGroupOutput, CONTROL_GROUP_TYPE } from './types'; | ||
import { ControlGroupContainer } from './embeddable/control_group_container'; | ||
|
||
export interface ControlGroupRendererProps { | ||
input?: Partial<Pick<ControlGroupInput, 'viewMode' | 'executionContext'>>; | ||
onEmbeddableLoad: (controlGroupContainer: ControlGroupContainer) => void; | ||
} | ||
|
||
export const ControlGroupRenderer = ({ input, onEmbeddableLoad }: ControlGroupRendererProps) => { | ||
const controlsRoot = useRef(null); | ||
const [controlGroupContainer, setControlGroupContainer] = useState<ControlGroupContainer>(); | ||
|
||
const id = useMemo(() => uuid.v4(), []); | ||
|
||
/** | ||
* Use Lifecycles to load initial control group container | ||
*/ | ||
useLifecycles( | ||
() => { | ||
const { embeddable } = pluginServices.getServices(); | ||
|
||
(async () => { | ||
const container = (await embeddable | ||
.getEmbeddableFactory< | ||
ControlGroupInput, | ||
ControlGroupOutput, | ||
IEmbeddable<ControlGroupInput, ControlGroupOutput> | ||
>(CONTROL_GROUP_TYPE) | ||
?.create({ id, ...getDefaultControlGroupInput(), ...input })) as ControlGroupContainer; | ||
|
||
if (controlsRoot.current) { | ||
container.render(controlsRoot.current); | ||
} | ||
setControlGroupContainer(container); | ||
onEmbeddableLoad(container); | ||
})(); | ||
}, | ||
() => { | ||
controlGroupContainer?.destroy(); | ||
} | ||
); | ||
|
||
/** | ||
* Update embeddable input when props input changes | ||
*/ | ||
useEffect(() => { | ||
let updateCanceled = false; | ||
(async () => { | ||
// check if applying input from props would result in any changes to the embeddable input | ||
const isInputEqual = await controlGroupContainer?.getExplicitInputIsEqual({ | ||
...controlGroupContainer?.getInput(), | ||
...input, | ||
}); | ||
if (!controlGroupContainer || isInputEqual || updateCanceled) return; | ||
controlGroupContainer.updateInput({ ...input }); | ||
})(); | ||
|
||
return () => { | ||
updateCanceled = true; | ||
}; | ||
}, [controlGroupContainer, input]); | ||
|
||
return <div ref={controlsRoot} />; | ||
}; | ||
|
||
// required for dynamic import using React.lazy() | ||
// eslint-disable-next-line import/no-default-export | ||
export default ControlGroupRenderer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
src/plugins/controls/public/control_group/editor/data_control_editor_tools.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* 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 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { IFieldSubTypeMulti } from '@kbn/es-query'; | ||
import { DataView } from '@kbn/data-views-plugin/common'; | ||
|
||
import { pluginServices } from '../../services'; | ||
import { DataControlFieldRegistry, IEditableControlFactory } from '../../types'; | ||
|
||
const dataControlFieldRegistryCache: { [key: string]: DataControlFieldRegistry } = {}; | ||
|
||
const doubleLinkFields = (dataView: DataView) => { | ||
// double link the parent-child relationship specifically for case-sensitivity support for options lists | ||
const fieldRegistry: DataControlFieldRegistry = {}; | ||
|
||
for (const field of dataView.fields.getAll()) { | ||
if (!fieldRegistry[field.name]) { | ||
fieldRegistry[field.name] = { field, compatibleControlTypes: [] }; | ||
} | ||
const parentFieldName = (field.subType as IFieldSubTypeMulti)?.multi?.parent; | ||
if (parentFieldName) { | ||
fieldRegistry[field.name].parentFieldName = parentFieldName; | ||
|
||
const parentField = dataView.getFieldByName(parentFieldName); | ||
if (!fieldRegistry[parentFieldName] && parentField) { | ||
fieldRegistry[parentFieldName] = { field: parentField, compatibleControlTypes: [] }; | ||
} | ||
fieldRegistry[parentFieldName].childFieldName = field.name; | ||
} | ||
} | ||
return fieldRegistry; | ||
}; | ||
|
||
export const loadFieldRegistryFromDataViewId = async ( | ||
dataViewId: string | ||
): Promise<DataControlFieldRegistry> => { | ||
if (dataControlFieldRegistryCache[dataViewId]) { | ||
return dataControlFieldRegistryCache[dataViewId]; | ||
} | ||
const { | ||
dataViews, | ||
controls: { getControlTypes, getControlFactory }, | ||
} = pluginServices.getServices(); | ||
const dataView = await dataViews.get(dataViewId); | ||
|
||
const newFieldRegistry: DataControlFieldRegistry = doubleLinkFields(dataView); | ||
|
||
const controlFactories = getControlTypes().map( | ||
(controlType) => getControlFactory(controlType) as IEditableControlFactory | ||
); | ||
dataView.fields.map((dataViewField) => { | ||
for (const factory of controlFactories) { | ||
if (factory.isFieldCompatible) { | ||
factory.isFieldCompatible(newFieldRegistry[dataViewField.name]); | ||
} | ||
} | ||
|
||
if (newFieldRegistry[dataViewField.name]?.compatibleControlTypes.length === 0) { | ||
delete newFieldRegistry[dataViewField.name]; | ||
} | ||
}); | ||
dataControlFieldRegistryCache[dataViewId] = newFieldRegistry; | ||
|
||
return newFieldRegistry; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.