-
-
Save kendrelaxman/baf09e74ff535059cb773c9838ee9188 to your computer and use it in GitHub Desktop.
import { Identity, ChannelClient } from 'openfin'; | |
class OpenFinChannelClient { | |
private channelClient: ChannelClient; | |
constructor(providerIdentity: Identity, channelName: string) { | |
this.channelClient = new ChannelClient(providerIdentity, channelName); | |
} | |
public async connect(): Promise<void> { | |
await this.channelClient.connect(); | |
} | |
public async disconnect(): Promise<void> { | |
await this.channelClient.disconnect(); | |
} | |
public subscribe<T>(topic: string, listener: (message: T, uuid: string, name: string) => void): void { | |
this.channelClient.subscribe(topic, listener); | |
} | |
public unsubscribe(topic: string): void { | |
this.channelClient.unsubscribe(topic); | |
} | |
public publish<T>(topic: string, message: T): void { | |
this.channelClient.publish(topic, message); | |
} | |
} | |
export default OpenFinChannelClient; | |
///////////////////////////// | |
import { fin } from 'openfin'; | |
import OpenFinChannelClient from './OpenFinChannelClient'; | |
async function connectToProvider() { | |
const providerIdentity = await fin.Application.wrap({ uuid: 'provider-uuid', name: 'provider-name' }); | |
const channelName = 'my-channel'; | |
const client = new OpenFinChannelClient(providerIdentity, channelName); | |
await client.connect(); | |
client.subscribe<string>('my-topic', (message, uuid, name) => { | |
console.log(`Received message ${message} from ${name} (${uuid})`); | |
}); | |
} | |
connectToProvider(); | |
///////////// | |
import { fin } from 'openfin'; | |
const channelName = 'my-channel'; | |
const providerIdentity = fin.Application.getCurrent(); | |
const channel = await fin.InterApplicationBus.Channel.create(channelName); | |
// Publish a message with the topic 'my-topic' | |
const message = 'Hello, world!'; | |
channel.publish('my-topic', message, providerIdentity.uuid); | |
////////////// | |
import { fin } from 'openfin'; | |
class OpenFinChannelProvider { | |
private channel: fin.InterApplicationBus.Channel; | |
private providerIdentity: fin.Identity; | |
constructor(channelName: string) { | |
this.channel = fin.InterApplicationBus.Channel.create(channelName); | |
this.providerIdentity = fin.Application.getCurrent(); | |
} | |
public async publishMessage<T>(topic: string, message: T): Promise<void> { | |
await this.channel.publish(topic, message, this.providerIdentity.uuid); | |
} | |
} | |
export default OpenFinChannelProvider; | |
////////////////// | |
import React from 'react'; | |
import OpenFinChannelProvider from './OpenFinChannelProvider'; | |
class MyProviderComponent extends React.Component { | |
private channelProvider: OpenFinChannelProvider; | |
constructor(props: any) { | |
super(props); | |
this.channelProvider = new OpenFinChannelProvider('my-channel'); | |
} | |
public async componentDidMount() { | |
// Publish a message with the topic 'my-topic' | |
const message = 'Hello, world!'; | |
await this.channelProvider.publishMessage('my-topic', message); | |
} | |
public render() { | |
return ( | |
<div> | |
// ... | |
</div> | |
); | |
} | |
} | |
export default MyProviderComponent; | |
//////// | |
import React from 'react'; | |
import { fin } from 'openfin'; | |
interface IState { | |
messages: string[]; | |
} | |
class MySubscriberComponent extends React.Component<{}, IState> { | |
private channelName = 'my-channel'; | |
private subscriberIdentity = fin.Application.getCurrent(); | |
constructor(props: any) { | |
super(props); | |
this.state = { | |
messages: [], | |
}; | |
// Create a new instance of the ChannelClient class and subscribe to messages | |
const client = new fin.InterApplicationBus.ChannelClient({ uuid: this.subscriberIdentity.uuid }); | |
client.onChannelConnect(this.channelName, () => { | |
client.subscribe(this.channelName, (topic, message, uuid) => { | |
this.handleMessageReceived(topic, message, uuid); | |
}); | |
}); | |
} | |
private handleMessageReceived(topic: string, message: any, uuid: string) { | |
console.log(`Received message: ${message}`); | |
// Add the message to the component state | |
this.setState((prevState) => ({ | |
messages: [...prevState.messages, message], | |
})); | |
} | |
public render() { | |
return ( | |
<div> | |
<h2>Messages:</h2> | |
<ul> | |
{this.state.messages.map((message) => ( | |
<li key={message}>{message}</li> | |
))} | |
</ul> | |
</div> | |
); | |
} | |
} | |
export default MySubscriberComponent; | |
//// | |
import { Identity, InterApplicationBus } from 'openfin/_v2/api/interappbus'; | |
interface WrapperProps { | |
appId: string; | |
} | |
class Wrapper { | |
private _bus: InterApplicationBus; | |
private _identity: Identity; | |
constructor(props: WrapperProps) { | |
if (typeof fin === 'undefined') { | |
throw new Error('OpenFin API not available'); | |
} | |
this._bus = fin.InterApplicationBus; | |
this._identity = { name: props.appId, uuid: fin.me.uuid }; | |
} | |
public async authenticate(): Promise<boolean> { | |
try { | |
await fin.System.authenticate(this._identity); | |
return true; | |
} catch (error) { | |
console.error('Error authenticating with OpenFin:', error); | |
return false; | |
} | |
} | |
public async send<T>(topic: string, message: T, targetIdentity: Identity): Promise<void> { | |
try { | |
await this.authenticate(); | |
await this._bus.send(targetIdentity, topic, message); | |
} catch (error) { | |
console.error('Error sending message:', error); | |
} | |
} | |
public async unsubscribe(topic: string, listener: Function): Promise<void> { | |
try { | |
await this.authenticate(); | |
await this._bus.unsubscribe(this._identity, topic, listener); | |
} catch (error) { | |
console.error('Error unsubscribing from topic:', error); | |
} | |
} | |
public async subscribe<T>(topic: string, listener: (message: T, uuid: string, name: string) => void): Promise<void> { | |
try { | |
await this.authenticate(); | |
await this._bus.subscribe(this._identity, topic, listener); | |
} catch (error) { | |
console.error('Error subscribing to topic:', error); | |
} | |
} | |
} | |
export default Wrapper; | |
// | |
import { useEffect, useRef } from 'react'; | |
function useIABTopic(topicName, callback) { | |
const callbackRef = useRef(callback); | |
useEffect(() => { | |
callbackRef.current = callback; | |
}, [callback]); | |
useEffect(() => { | |
const handleTopicMessage = (message, uuid, name) => { | |
callbackRef.current(message, uuid, name); | |
}; | |
fin.InterApplicationBus.subscribe(topicName, handleTopicMessage); | |
return () => { | |
fin.InterApplicationBus.unsubscribe(topicName, handleTopicMessage); | |
}; | |
}, [topicName]); | |
} | |
export default useIABTopic; | |
// | |
import { useEffect, useRef } from 'react'; | |
function useIABTopic(topicName, callback) { | |
const callbackRef = useRef(callback); | |
useEffect(() => { | |
callbackRef.current = callback; | |
}, [callback]); | |
useEffect(() => { | |
const handleTopicMessage = (message, uuid, name) => { | |
callbackRef.current(message, uuid, name); | |
}; | |
fin.InterApplicationBus.subscribe(topicName, handleTopicMessage); | |
return () => { | |
fin.InterApplicationBus.unsubscribe(topicName, handleTopicMessage); | |
}; | |
}, [topicName]); | |
} | |
export default useIABTopic; |
import { useState, useEffect } from 'react';
function useMyCustomClass() {
const [instance, setInstance] = useState(null);
function getInstance() {
if (instance) {
return instance;
}
const newInstance = new MyClass();
setInstance(newInstance);
return newInstance;
}
useEffect(() => {
return () => {
if (instance) {
// destroy the instance when the hook is unmounted
instance.destroy();
}
};
}, [instance]);
return getInstance;
}
class MyClass {
// Define your class methods and properties here
destroy() {
// Define a method to destroy the instance if needed
}
}
export default useMyCustomClass;
function MyComponent() {
const getInstance = useMyCustomClass();
const myInstance = getInstance();
// Use myInstance here
}
import React, { useState } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
const MyGridComponent = () => {
const [rowData, setRowData] = useState([]);
const onGridReady = (params) => {
const { api } = params;
// Set up your column definitions and other configuration options here
// ...
// Set up the initial data for the grid
const initialData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 },
];
setRowData(initialData);
// Set up the grid's onSortChanged event listener
api.addEventListener('sortChanged', () => {
const sortedData = [];
for (let i = 0; i < api.getDisplayedRowCount(); i++) {
sortedData.push(api.getDisplayedRowAtIndex(i).data);
}
console.log('Sorted Data:', sortedData);
});
};
return (
<div className="ag-theme-alpine" style={{ height: '200px', width: '600px' }}>
{/* Add your column definitions here */}
);
};
export default MyGridComponent;
// Test cases
const axios = require('axios');
const ClassA = require('./ClassA');
const ClassB = require('./ClassB');
const ClassC = require('./ClassC');
jest.mock('axios');
describe('ClassC', () => {
let classC;
beforeEach(() => {
// mock process.env to set API_ENDPOINT value to dummy URL
process.env.API_ENDPOINT = 'https://example.com/api';
const classA = new ClassA();
const classB = new ClassB(classA);
classC = new ClassC(classB);
});
afterEach(() => {
jest.resetAllMocks();
// reset process.env to its original state
delete process.env.API_ENDPOINT;
});
it('should retrieve authenticated data from ClassA via ClassB', async () => {
const username = 'testuser';
const password = 'testpassword';
const authToken = 'testauthtoken';
const authenticatedData = { foo: 'bar' };
// mock authenticateUser() method of ClassA to return authToken
jest.spyOn(classC.classBInstance.classAInstance, 'authenticateUser')
.mockResolvedValue(authToken);
// mock get() method of axios to return authenticatedData
axios.get.mockResolvedValue({ data: authenticatedData });
const result = await classC.getDataFromClassB(username, password);
expect(result).toEqual(authenticatedData);
expect(axios.get).toHaveBeenCalledWith('https://example.com/api', {
headers: { Authorization: `Bearer ${authToken}` },
});
expect(classC.classBInstance.classAInstance.authenticateUser)
.toHaveBeenCalledWith(username, password);
});
});
it('should wait for Core.loadData to complete if multiple calls are made in quick succession', async () => {
// Arrange
const config1 = { queryToken: 'test1' };
const config2 = { queryToken: 'test1' };
const config3 = { queryToken: 'test2' };
const isRequestFromCache = false;
const data = { prop1: 'value1', prop2: 'value2' };
const callback1 = jest.fn();
const callback2 = jest.fn();
const callback3 = jest.fn();
jest.spyOn(Core, 'loadData').mockImplementationOnce(
() =>
new Promise((resolve) => {
setTimeout(() => resolve(data), 1000);
})
);
// Act
const instance = new A();
instance.loadData(config1, isRequestFromCache, callback1);
instance.loadData(config2, isRequestFromCache, callback2);
instance.loadData(config3, isRequestFromCache, callback3);
await new Promise((resolve) => setTimeout(resolve, 500));
expect(Core.loadData).toHaveBeenCalledTimes(1);
await new Promise((resolve) => setTimeout(resolve, 1000));
expect(Core.loadData).toHaveBeenCalledTimes(1);
expect(callback1).toHaveBeenCalledWith(data);
expect(callback2).toHaveBeenCalledWith(data);
await new Promise((resolve) => setTimeout(resolve, 1000));
expect(Core.loadData).toHaveBeenCalledTimes(2);
expect(callback3).toHaveBeenCalledWith(data);
});
{
"gridLayout": {
"rows": 3,
"columns": 4,
"fields": [
{
"row": 1,
"column": 2,
"type": "Field",
"label": "Field 1",
"defaultValue": ""
},
{
"row": 2,
"column": 3,
"type": "Label",
"label": "Label 1",
"defaultValue": "Default Value 1"
},
{
"row": 3,
"column": 1,
"type": "Field",
"label": "Field 2",
"defaultValue": ""
},
{
"row": 1,
"column": 4,
"type": "Label",
"label": "Label 2",
"defaultValue": "Default Value 2"
}
]
}
}
import React from 'react';
function GridLayout(props) {
const { rows, columns, fields } = props.data.gridLayout;
// Create an empty grid layout
const grid = [];
for (let i = 0; i < rows; i++) {
grid[i] = [];
for (let j = 0; j < columns; j++) {
grid[i][j] = null;
}
}
// Place the fields and labels in the grid layout
fields.forEach((field) => {
const { row, column, type, label, defaultValue } = field;
const component = type === 'Field' ? (
) : (
{defaultValue}
);
grid[row - 1][column - 1] = (
<div key={${row}-${column}
} className="grid-item">
{component}
{label}
);
});
// Render the grid layout
return (
{grid.map((row, rowIndex) => (
{row.map((item, columnIndex) => (
{item}
))}
))}
);
}
export default GridLayout;
{
"panel": {
"columns": [
{
"name": "Column 1",
"rows": [
{
"name": "Row 1",
"components": [
{
"type": "Label",
"label": "Label 1",
"defaultValue": "Default Value 1"
},
{
"type": "InputField",
"label": "Input Field 1",
"defaultValue": ""
}
]
},
{
"name": "Row 2",
"components": [
{
"type": "Dropdown",
"label": "Dropdown Field 1",
"options": ["Option 1", "Option 2", "Option 3"],
"defaultValue": "Option 1"
}
]
}
]
},
{
"name": "Column 2",
"rows": [
{
"name": "Row 1",
"components": [
{
"type": "Label",
"label": "Label 2",
"defaultValue": "Default Value 2"
},
{
"type": "InputField",
"label": "Input Field 2",
"defaultValue": ""
}
]
},
{
"name": "Row 2",
"components": [
{
"type": "Dropdown",
"label": "Dropdown Field 2",
"options": ["Option 1", "Option 2", "Option 3"],
"defaultValue": "Option 1"
}
]
}
]
}
]
}
}
.container {
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.group {
border: 1px solid #ccc;
padding: 20px;
}
.fields-container {
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.field {
display: grid;
gap: 5px;
grid-template-columns: max-content auto max-content;
align-items: center;
}
.field label {
justify-self: start;
}
.field span {
justify-self: end;
}
import React from 'react';
import './JsonComponent.css'; // Import the CSS file for styling
const JsonComponent = ({ jsonData, dataObject }) => {
// Render the JSON structure
const renderContainer = (container) => {
return (
{container.groups.map((group, index) => (
{group.name}
{renderFields(group.fields)}
))}
);
};
const renderFields = (fields) => {
return (
{fields.map((field, index) => (
{field.label}
{renderControl(field.control)}
{field.endRow}
))}
);
};
const renderControl = (control) => {
const { type, initialValue, dataKey, optionsDataKey } = control[0];
switch (type) {
case 'input':
return (
<input
type="text"
value={initialValue}
onChange={() => {}}
/>
);
case 'dropdown':
const options = dataObject[optionsDataKey] || [];
return (
<select value={initialValue} onChange={() => {}}>
{options.map((option, optionIndex) => (
<option key={optionIndex} value={option}>
{option}
</option>
))}
</select>
);
default:
return null;
}
};
return (
{jsonData.container.map((container, index) => (
{renderContainer(container)}
))}
);
};
export default JsonComponent;
const mergeObjects = (target, source, sourceName) => {
for (const key in source) {
if (source.hasOwnProperty(key)) {
const propertyName = ${key}_metadata
;
target[propertyName] = sourceName;
if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
if (!target.hasOwnProperty(key)) {
target[key] = {};
}
mergeObjects(target[key], source[key], sourceName);
} else {
const propertyValue = source[key];
target[key] = propertyValue;
if (typeof propertyValue !== 'object' || propertyValue === null || Array.isArray(propertyValue)) {
target[propertyName] = sourceName;
}
}
}
}
};
function getProperty(obj: any, propertyString: string): any {
const properties = propertyString.split('.');
return properties.reduce((currentObj, prop) => {
try {
return currentObj[prop];
} catch (error) {
return undefined;
}
}, obj);
}
function listen() {
const subject = new Subject();
// some code here that calls
subject.next
return subject.asObservable();
}