diff --git a/app/javascript/custom-typings.ts b/app/javascript/custom-typings.ts new file mode 100644 index 000000000000..1ba5fa88554a --- /dev/null +++ b/app/javascript/custom-typings.ts @@ -0,0 +1,2 @@ +declare var ManageIQ: any; +declare var Rx: any; \ No newline at end of file diff --git a/app/javascript/extensible-components/index.ts b/app/javascript/extensible-components/index.ts new file mode 100644 index 000000000000..879176ee5e58 --- /dev/null +++ b/app/javascript/extensible-components/index.ts @@ -0,0 +1,49 @@ +import { IExtensionComponent, IMiQApiCallback } from './lib'; + +/** + * Class for easy creation of extensible component. + */ +export class ExtensibleComponent { + public unsubscribe: Function; + constructor(public name: string, public api: IMiQApiCallback, public render: IMiQApiCallback){} +} + +/** + * Create new object which will hold extension components on MiQ main object. + */ +ManageIQ.extensionComponents = ManageIQ.extensionComponents || {}; + +/** + * Subject from from Rxjs to send message that we want to register new component. + */ +ManageIQ.extensionComponents.source = new Rx.Subject(); + +/** + * Components will be saved in items which will be set. To easy remove of components which no longer exists. + */ +ManageIQ.extensionComponents.items = new Set(); + +/** + * Helper function to create new component. + * @param name string name of new component. + * @param api callback functions to change inner logic of component. + * @param render callback function to apply render functions. + */ +ManageIQ.extensionComponents.newComponent = function(name: string, api?: IMiQApiCallback, render?: IMiQApiCallback) { + const newCmp = new ExtensibleComponent(name, api, render); + ManageIQ.extensionComponents.source.onNext({action: 'add', payload: newCmp}); +} + +/** + * Subscribe to extensionComponents source to add new components to items object. + */ +ManageIQ.extensionComponents.source.subscribe((event: IExtensionComponent) => { + if (event.action === 'add' && event.hasOwnProperty('payload')) { + event.payload.unsubscribe = () => { + ManageIQ.extensionComponents.items.delete(event.payload); + } + ManageIQ.extensionComponents.items.add(event.payload); + } else { + throw new Error('Unsupported action with extension components.'); + } +}); \ No newline at end of file diff --git a/app/javascript/extensible-components/lib.ts b/app/javascript/extensible-components/lib.ts new file mode 100644 index 000000000000..d416a0bd0703 --- /dev/null +++ b/app/javascript/extensible-components/lib.ts @@ -0,0 +1,28 @@ +export interface IExtensionComponent { + action: string; + payload: any; +} + +export interface IMiQApiCallback { + [propName: string]: Function; +} + +export interface IExtensibleComponent { + extensibleComponent: any; + apiCallbacks: () => IMiQApiCallback; + renderCallbacks: () => IMiQApiCallback; +} + +export const extensionSource = ManageIQ.extensionComponents.source; + +export const extensionItems = ManageIQ.extensionComponents.items; + +/** + * Helper function to create new component. + * @param name string name of new component. + * @param api callback functions to change inner logic of component. + * @param render callback function to apply render functions. + */ +export function newComponent(name: string, api?: IMiQApiCallback, render?: IMiQApiCallback) { + ManageIQ.extensionComponents.newComponent(name, api, render); +} \ No newline at end of file diff --git a/app/javascript/packs/extensible-componenets-common.js b/app/javascript/packs/extensible-componenets-common.js new file mode 100644 index 000000000000..52db0e70974e --- /dev/null +++ b/app/javascript/packs/extensible-componenets-common.js @@ -0,0 +1 @@ +require('../extensible-components'); \ No newline at end of file