Use an external component action inside a search
The following React example uses an external component action inside a search. This example shows how to use the setModalOperations property to add buttons and associated behavior to the modal footer and perform validation. The setModalOperations property is a function with an array of modal operations.
Note
The setModalOperations property is an extra property that is only available on external components within the external component action.
A modal operation has the following interface.
RequestResponse
interface ModalOperationConfig {
name: string;
id: string;
label: string;
displayType?: DisplayType;
className?: string;
onValidate?: () => boolean | Promise<boolean>;
onClick?: (event?: unknown) => void | Promise<void>;
onMouseOver?: (event?: unknown) => void | Promise<void>;
onContextMenu?: (event?: unknown) => void | Promise<void>;
}
The options for the displayType are: link, default, primary, and secondary.
RequestResponse
import ReactDOM from "react-dom";
import React from "react";
const OptionsContext = React.createContext<any>(null);
type ModalOperationConfig = {
name: string;
id: string;
label: string;
displayType?: "link" | "default" | "primary" | "secondary" | "none";
className?: string;
onValidate?: () => boolean | Promise<boolean>;
onClick?: (event?: unknown) => void | Promise<void>;
onMouseOver?: (event?: unknown) => void | Promise<void>;
onContextMenu?: (event?: unknown) => void | Promise<void>;
};
export default function createExternalRoot(container: HTMLElement) {
return {
render(context: any) {
const {
api: { notifier },
options: { setModalOperations, ...options },
} = context;
const okButtonConfig: ModalOperationConfig = {
name: "ok",
id: "ok",
label: "Ok",
displayType: "primary",
onValidate: () => {
console.log("validating async...");
return new Promise((resolve) =>
setTimeout(() => {
const isValid = Math.random() > 0.5;
if (!isValid) {
notifier.notifyError("Invalid!");
}
resolve(isValid);
}, 500)
);
},
onClick: () => {
notifier.notifySuccess("Success!");
},
onMouseOver: () => {
console.log("mouseover");
},
};
const cancelButtonConfig: ModalOperationConfig = {
name: "cancel",
id: "cancel",
label: "Cancel",
onClick: () => {
notifier.notifyInfo("Canceled");
},
};
setModalOperations([okButtonConfig, cancelButtonConfig]);
ReactDOM.render(
<OptionsContext.Provider value={options}>
<OptionsContext.Consumer>
{(options) => {
return (
<>
<div>
Showing a modal for entity with id {options.entityId}.
</div>
<div>Showing a rendition of the entity</div>
<img
src={context?.entity?.renditions?.preview?.[0]}
style={{ maxWidth: "100%" }}
/>
</>
);
}}
</OptionsContext.Consumer>
</OptionsContext.Provider>,
container
);
},
unmount() {
ReactDOM.unmountComponentAtNode(container);
},
};
}