UNPKG

novo-elements

Version:

Bullhorn's NOVO Element Repository for Angular 2

576 lines (545 loc) 20.9 kB
// NG2 import { Injectable } from '@angular/core'; // Vendor import { Subject } from 'rxjs/Subject'; export enum AppBridgeHandler { HTTP, OPEN, OPEN_LIST, CLOSE, REFRESH, PIN, REGISTER, UPDATE, REQUEST_DATA } export type NovoApps = 'record' | 'add' | 'fast-add' | 'custom'; export interface IAppBridgeOpenEvent { type: NovoApps; entityType: string; entityId?: string; data?: any; passthrough?: string; } export type MosaicLists = 'Candidate' | 'ClientContact' | 'ClientCorporation' | 'JobOrder' | 'JobSubmission' | 'JobPosting' | 'Placement' | 'Lead' | 'Opportunity'; export interface IAppBridgeOpenListEvent { type: MosaicLists; keywords?: Array<string>; criteria?: any; } export type NovoDataType = 'entitlements' | 'settings' | 'user'; export interface IAppBridgeRequestDataEvent { type: NovoDataType; } const HTTP_VERBS = { GET: 'get', POST: 'post', PUT: 'put', DELETE: 'delete' }; const MESSAGE_TYPES = { REGISTER: 'register', OPEN: 'open', OPEN_LIST: 'openList', CLOSE: 'close', REFRESH: 'refresh', PIN: 'pin', UPDATE: 'update', HTTP_GET: 'httpGET', HTTP_POST: 'httpPOST', HTTP_PUT: 'httpPUT', HTTP_DELETE: 'httpDELETE', CUSTOM_EVENT: 'customEvent', REQUEST_DATA: 'requestData' }; declare const postRobot: any; export class AppBridge { public id: string = `${Date.now()}`; public traceName: string; public windowName: string; private _registeredFrames: any[] = []; private _handlers = {}; private _tracing: boolean = false; private _eventListeners: any = {}; // Type? constructor(traceName?: string) { this.traceName = traceName; if (postRobot) { postRobot.CONFIG.LOG_LEVEL = 'error'; try { this._setupHandlers(); } catch (error) { // No op } } } set tracing(tracing: boolean) { this._tracing = tracing; } public handle(type: AppBridgeHandler, handler: Function) { this._handlers[type] = handler; } private _trace(eventType, event) { if (this._tracing) { console.log(`[${this.traceName || this.id}] "${eventType}"`, event); // tslint:disable-line } } private _setupHandlers(): void { // Register postRobot.on(MESSAGE_TYPES.REGISTER, (event) => { this._trace(MESSAGE_TYPES.REGISTER, event); this._registeredFrames.push(event); return this.register(event.data).then(windowName => { this.windowName = windowName; return { windowName }; }); }); // Update postRobot.on(MESSAGE_TYPES.UPDATE, (event) => { this._trace(MESSAGE_TYPES.UPDATE, event); return this.update(event.data).then(success => { return { success }; }); }); // Open postRobot.on(MESSAGE_TYPES.OPEN, (event) => { this._trace(MESSAGE_TYPES.OPEN, event); return this.open(event.data).then(success => { return { success }; }); }); postRobot.on(MESSAGE_TYPES.OPEN_LIST, (event) => { this._trace(MESSAGE_TYPES.OPEN_LIST, event); return this.openList(event.data).then(success => { return { success }; }); }); // Close postRobot.on(MESSAGE_TYPES.CLOSE, (event) => { this._trace(MESSAGE_TYPES.CLOSE, event); const index = this._registeredFrames.findIndex(frame => frame.data.id === event.data.id); if (index !== -1) { this._registeredFrames.splice(index, 1); } return this.close(event.data).then(success => { return { success }; }); }); // Refresh postRobot.on(MESSAGE_TYPES.REFRESH, (event) => { this._trace(MESSAGE_TYPES.REFRESH, event); return this.refresh(event.data).then(success => { return { success }; }); }); // PIN postRobot.on(MESSAGE_TYPES.PIN, (event) => { this._trace(MESSAGE_TYPES.PIN, event); return this.pin(event.data).then(success => { return { success }; }); }); // REQUEST_DATA postRobot.on(MESSAGE_TYPES.REQUEST_DATA, (event) => { this._trace(MESSAGE_TYPES.REQUEST_DATA, event); return this.requestData(event.data).then(success => { return { success }; }); }); // HTTP-GET postRobot.on(MESSAGE_TYPES.HTTP_GET, (event) => { this._trace(MESSAGE_TYPES.HTTP_GET, event); return this.httpGET(event.data.relativeURL).then(result => { return { data: result.data, error: result.error }; }); }); // HTTP-POST postRobot.on(MESSAGE_TYPES.HTTP_POST, (event) => { this._trace(MESSAGE_TYPES.HTTP_POST, event); return this.httpPOST(event.data.relativeURL, event.data.data).then(result => { return { data: result.data, error: result.error }; }); }); // HTTP-PUT postRobot.on(MESSAGE_TYPES.HTTP_PUT, (event) => { this._trace(MESSAGE_TYPES.HTTP_PUT, event); return this.httpPUT(event.data.relativeURL, event.data.data).then((result) => { return { data: result.data, error: result.error }; }); }); // HTTP-DELETE postRobot.on(MESSAGE_TYPES.HTTP_DELETE, (event) => { this._trace(MESSAGE_TYPES.HTTP_DELETE, event); return this.httpDELETE(event.data.relativeURL).then(result => { return { data: result.data, error: result.error }; }); }); // Custom Events postRobot.on(MESSAGE_TYPES.CUSTOM_EVENT, (event) => { this._trace(MESSAGE_TYPES.CUSTOM_EVENT, event); if (this._eventListeners[event.data.event]) { this._eventListeners[event.data.event].forEach((listener) => { listener(event.data.data); }); } if (this._registeredFrames.length > 0) { this._registeredFrames.forEach(frame => { postRobot.send(frame.source, MESSAGE_TYPES.CUSTOM_EVENT, event.data); }); } }); } /** * Fires or responds to an open event * @param packet any - packet of data to send with the open event */ public open(packet: IAppBridgeOpenEvent): Promise<boolean> { Object.assign(packet, { id: this.id, windowName: this.windowName }); return new Promise<boolean>((resolve, reject) => { if (this._handlers[AppBridgeHandler.OPEN]) { this._handlers[AppBridgeHandler.OPEN](packet, (success: boolean) => { if (success) { resolve(true); } else { reject(false); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.OPEN, packet).then((event) => { this._trace(`${MESSAGE_TYPES.OPEN} (callback)`, event); if (event.data) { resolve(true); } else { reject(false); } }).catch((err) => { reject(false); }); } }); } /** * Fires or responds to an openList event * @param packet any - packet of data to send with the open event */ public openList(packet: IAppBridgeOpenListEvent): Promise<boolean> { let openListPacket = {}; Object.assign(openListPacket, { type: 'List', entityType: packet.type, keywords: packet.keywords, criteria: packet.criteria }); return new Promise<boolean>((resolve, reject) => { if (this._handlers[AppBridgeHandler.OPEN_LIST]) { this._handlers[AppBridgeHandler.OPEN_LIST](packet, (success: boolean) => { if (success) { resolve(true); } else { reject(false); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.OPEN_LIST, packet).then((event) => { this._trace(`${MESSAGE_TYPES.OPEN_LIST} (callback)`, event); if (event.data) { resolve(true); } else { reject(false); } }).catch((err) => { reject(false); }); } }); } /** * Fires or responds to an close event * @param packet any - packet of data to send with the close event */ public update(packet: any): Promise<boolean> { Object.assign(packet, { id: this.id, windowName: this.windowName }); return new Promise<boolean>((resolve, reject) => { if (this._handlers[AppBridgeHandler.UPDATE]) { this._handlers[AppBridgeHandler.UPDATE](packet, (success: boolean) => { if (success) { resolve(true); } else { reject(false); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.UPDATE, packet).then((event) => { this._trace(`${MESSAGE_TYPES.UPDATE} (callback)`, event); if (event.data) { resolve(true); } else { reject(false); } }).catch((err) => { reject(false); }); } }); } /** * Fires or responds to an close event * @param packet any - packet of data to send with the close event */ public close(packet: any): Promise<boolean> { Object.assign(packet, { id: this.id, windowName: this.windowName }); return new Promise<boolean>((resolve, reject) => { if (this._handlers[AppBridgeHandler.CLOSE]) { this._handlers[AppBridgeHandler.CLOSE](packet, (success: boolean) => { if (success) { resolve(true); } else { reject(false); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.CLOSE, packet).then((event) => { this._trace(`${MESSAGE_TYPES.CLOSE} (callback)`, event); if (event.data) { resolve(true); } else { reject(false); } }).catch((err) => { reject(false); }); } }); } /** * Fires or responds to an close event * @param packet any - packet of data to send with the close event */ public refresh(packet: any): Promise<boolean> { Object.assign(packet, { id: this.id, windowName: this.windowName }); return new Promise<boolean>((resolve, reject) => { if (this._handlers[AppBridgeHandler.REFRESH]) { this._handlers[AppBridgeHandler.REFRESH](packet, (success: boolean) => { if (success) { resolve(true); } else { reject(false); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.REFRESH, packet).then((event) => { this._trace(`${MESSAGE_TYPES.REFRESH} (callback)`, event); if (event.data) { resolve(true); } else { reject(false); } }).catch((err) => { reject(false); }); } }); } /** * Fires or responds to a pin event * @param packet any - packet of data to send with the pin event */ public pin(packet: any): Promise<boolean> { Object.assign(packet, { id: this.id, windowName: this.windowName }); return new Promise<boolean>((resolve, reject) => { if (this._handlers[AppBridgeHandler.PIN]) { this._handlers[AppBridgeHandler.PIN](packet, (success: boolean) => { if (success) { resolve(true); } else { reject(false); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.PIN, packet).then((event) => { this._trace(`${MESSAGE_TYPES.PIN} (callback)`, event); if (event.data) { resolve(true); } else { reject(false); } }).catch((err) => { reject(false); }); } }); } /** * Fires or responds to a requestData event * @param packet any - packet of data to send with the requestData event */ public requestData(packet: any): Promise<any> { Object.assign(packet, { id: this.id, windowName: this.windowName }); return new Promise<any>((resolve, reject) => { if (this._handlers[AppBridgeHandler.REQUEST_DATA]) { this._handlers[AppBridgeHandler.REQUEST_DATA](packet, (data: any) => { if (data) { resolve({ data }); } else { reject(false); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.REQUEST_DATA, packet).then((event) => { this._trace(`${MESSAGE_TYPES.REQUEST_DATA} (callback)`, event); if (event.data) { resolve({ data: event.data.data }); } else { reject(false); } }).catch((err) => { reject(false); }); } }); } /** * Fires or responds to an register event * @param packet any - packet of data to send with the event */ public register(packet: { title?: string, url?: string, color?: string } = {}): Promise<string> { Object.assign(packet, { id: this.id, windowName: this.windowName }); return new Promise<string>((resolve, reject) => { if (this._handlers[AppBridgeHandler.REGISTER]) { this._handlers[AppBridgeHandler.REGISTER](packet, (windowName: string) => { if (windowName) { resolve(windowName); } else { resolve(null); } }); } else { postRobot.sendToParent(MESSAGE_TYPES.REGISTER, packet).then((event) => { this._trace(`${MESSAGE_TYPES.REGISTER} (callback)`, event); if (event.data) { this.windowName = event.data.windowName; resolve(event.data.windowName); } else { resolve(null); } }).catch((err) => { this._trace(`${MESSAGE_TYPES.REGISTER} - FAILED - (no parent)`, err); resolve(null); }); } }); } /** * Fires or responds to an HTTP_GET event * @param packet any - packet of data to send with the event */ public httpGET(relativeURL: string): Promise<any> { return new Promise<any>((resolve, reject) => { if (this._handlers[AppBridgeHandler.HTTP]) { this._handlers[AppBridgeHandler.HTTP]({ verb: HTTP_VERBS.GET, relativeURL: relativeURL }, (data: any, error: any) => { resolve({ data, error }); }); } else { postRobot.sendToParent(MESSAGE_TYPES.HTTP_GET, { relativeURL }).then((event: any) => { resolve({ data: event.data.data, error: event.data.error }); }).catch((err) => { reject(null); }); } }); } /** * Fires or responds to an HTTP_POST event * @param packet any - packet of data to send with the event */ public httpPOST(relativeURL: string, postData: any): Promise<any> { return new Promise<any>((resolve, reject) => { if (this._handlers[AppBridgeHandler.HTTP]) { this._handlers[AppBridgeHandler.HTTP]({ verb: HTTP_VERBS.POST, relativeURL: relativeURL, data: postData }, (data: any, error: any) => { resolve({ data, error }); }); } else { postRobot.sendToParent(MESSAGE_TYPES.HTTP_POST, { relativeURL: relativeURL, data: postData }).then((event: any) => { resolve({ data: event.data.data, error: event.data.error }); }).catch((err) => { reject(null); }); } }); } /** * Fires or responds to an HTTP_PUT event * @param packet any - packet of data to send with the event */ public httpPUT(relativeURL: string, putData: any): Promise<any> { return new Promise<any>((resolve, reject) => { if (this._handlers[AppBridgeHandler.HTTP]) { this._handlers[AppBridgeHandler.HTTP]({ verb: HTTP_VERBS.PUT, relativeURL: relativeURL, data: putData }, (data: any, error: any) => { resolve({ data, error }); }); } else { postRobot.sendToParent(MESSAGE_TYPES.HTTP_PUT, { relativeURL: relativeURL, data: putData }).then((event: any) => { resolve({ data: event.data.data, error: event.data.error }); }).catch((err) => { reject(null); }); } }); } /** * Fires or responds to an HTTP_DELETE event * @param packet any - packet of data to send with the event */ public httpDELETE(relativeURL: string): Promise<any> { return new Promise<any>((resolve, reject) => { if (this._handlers[AppBridgeHandler.HTTP]) { this._handlers[AppBridgeHandler.HTTP]({ verb: HTTP_VERBS.DELETE, relativeURL: relativeURL }, (data: any, error: any) => { resolve({ data, error }); }); } else { postRobot.sendToParent(MESSAGE_TYPES.HTTP_DELETE, { relativeURL }).then((event: any) => { resolve({ data: event.data.data, error: event.data.error }); }).catch((err) => { reject(null); }); } }); } /** * Fires a custom event to anywhere in the application * @param event string - event name to fire * @param data any - data to be sent along with the event */ public fireEvent(event: string, data: any): Promise<any> { return new Promise<any>((resolve, reject) => { postRobot.sendToParent(MESSAGE_TYPES.CUSTOM_EVENT, { event, data }).then((e: any) => { resolve(e); }).catch((err) => { reject(null); }); }); } /** * Fires a custom event to all registered frames * @param event string - event name to fire * @param data any - data to be sent along with the event */ public fireEventToChildren(event: string, data: any): void { if (this._registeredFrames.length > 0) { this._registeredFrames.forEach(frame => { postRobot.send(frame.source, MESSAGE_TYPES.CUSTOM_EVENT, { eventType: event, data: data }); }); } } /** * Adds an event listener to a custom event * @param event string - event name to listen to * @param callback function - callback to be fired when an event is caught */ public addEventListener(event: string, callback: Function): void { if (!this._eventListeners[event]) { this._eventListeners[event] = []; } this._eventListeners[event].push(callback); } }