Skip to content

Add default extensions for testing inter widget communication #7

@itechify

Description

@itechify

Add two new default extensions to es-home (or es-common-extensions?) for testing iwc channels through shouting (channelShouter) and listening (channelListener).

The channel shouter extension could be based on something like the following but it should be defined like an extension:

import React, { useState, useRef, useEffect } from 'react';
import ReactDOM from "react-dom";
import 'primeicons/primeicons.css';
import 'primereact/resources/themes/lara-dark-indigo/theme.css';
import 'primereact/resources/primereact.css';
//import 'primeflex/primeflex.css';
import "./App.css";
import JSONInput from "react-json-editor-ajrm/index";
import locale from "react-json-editor-ajrm/locale/en";
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { Toast } from 'primereact/toast';
import {
  initialize,
  publishJson
} from "@moesol/inter-widget-communication";


const mode = import.meta.env.NODE_ENV;

export default function App() {
  useEffect(() => {
    const provider = new URLSearchParams(window.location.search).get('iwc') || 'broadcast';
    const busUrl = new URLSearchParams(window.location.search).get('busUrl') || '/es/ui/bcst-bus/';

    if (provider && busUrl) {
      initialize({
        busUrl,
        provider
      });
    }

  }, []);
  const toast = useRef(null);
  const [payload, setPayload] = useState();
  const [channel, setChannel] = useState('');
  const showError = (error, content) => {
    toast.current.show({ severity: 'error', summary: error });
  }
  const onBroadcast = () => {
    if (channel.length === 0) {
      showError('Channel not specified');
      return;
    }
    if (!payload) {
      showError('Payload not specified');
      return;
    }
    if (payload.error) {
      showError('Error in payloads format');
    }
    // all is ok, lets try to broadcast.
    publishJson(channel, payload.jsObject);


  }

  /**
   * Rendering this JSONInput component with some properties
   */
  return (
    <div>
      <Toast ref={toast} position="bottom-right" />

      <h5>Channel</h5>
      <div className="grid">
      <InputText className="col-fixed" style={{ width: '20em', height: '2.25em', marginLeft: '1em' }}  value={channel} onChange={(e) => setChannel(e.target.value)} />
      <Button className="col-fixed" style={{   marginLeft: '0.5em', height: '2.25em', marginBottom: '0.15em' }} label="Broadcast" className="p-button-sm" onClick={onBroadcast} />
      </div>
      <h5>Payload</h5>
      <div className="grid" style={{ marginLeft: '1em' }} >
      <JSONInput

        locale={locale}
        colors={{
          string: "#DAA520" // overrides theme colors with whatever color value you want
        }}
        height="30em"
        width="45em"

        onChange={setPayload}
      />
    </div>

    </div>
  );
}

ReactDOM.render(<App />, document.querySelector("#root"));

Similarly for the channel listener:

import React, { useState, useRef, useEffect } from 'react';
import ReactDOM from "react-dom";
import 'primeicons/primeicons.css';
import 'primereact/resources/themes/lara-dark-indigo/theme.css';
import 'primereact/resources/primereact.css';
import 'primeflex/primeflex.css';
import "./App.css";
import JSONInput from "react-json-editor-ajrm/index";
import locale from "react-json-editor-ajrm/locale/en";
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { ListBox } from 'primereact/listbox';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Toast } from 'primereact/toast';
import {
  initialize,
  subscribe,
  unsubscribe
} from "@moesol/inter-widget-communication";
export default function App() {
  const toast = useRef(null);
  const [channel, setChannel] = useState('');
  const [channels, setChannels] = useState([]);
  const [messages, setMessages] = useState([]);
  const [payload, setPayload] = useState();
  const showError = (error, content) => {
    toast.current.show({ severity: 'error', summary: error });
  }

  useEffect(() => {
    const provider = new URLSearchParams(window.location.search).get('iwc') || 'broadcast';
    const busUrl = new URLSearchParams(window.location.search).get('busUrl') || '/es/ui/bcst-bus/';

    if (provider && busUrl) {
      initialize({
        busUrl,
        provider
      });
    }
  },[]);

  const onAdd = () => {
    if (channel.length === 0) {
      showError('Channel not specified');
      return;
    }
    if (channels.find(element => element === channel)) {
      showError('Channel is already specified specified');
      return;
    }
    setChannels(channels => {
      return [...channels, channel];
    });

    subscribe(channel, (sender, payload, channel) => {
      const msg = { channel, payload };
      setMessages(messages => {
        return [msg, ...messages];
      });
      //setPayload(JSON.parse(payload));
    });
  }

  const onClear = () => {
    // lets unscribe all the channels
    channels.forEach((channel) => {
      unsubscribe(channel);
    });
    setChannels([]);
  }
  const onClearMsgs = () => {
    setMessages([]);
  }
  const setSelected = (e) => {
    const payload = JSON.parse(e.value.payload);
    setPayload(payload);
  }
  /**
   * Rendering this JSONInput component with some properties
   */
  return (
    <div>
      <Toast ref={toast} position="bottom-right" />
      <div className="grid" >
        <InputText className="col-fixed" style={{ width: '20em', marginLeft: '1em' }} value={channel} onChange={(e) => setChannel(e.target.value)} />
        <Button style={{ marginLeft: '1em' }} label="Add Channel" className="col-fixed p-button-sm" onClick={onAdd} />
        <Button style={{ marginLeft: '1em' }} label="Clear Channels" className="col-fixed p-button-sm" onClick={onClear} />
        <Button style={{ marginLeft: '1em' }} label="Clear Messages" className="col-fixed p-button-sm" onClick={onClearMsgs} />
      </div>
      <ListBox options={channels} style={{ width: '20em', marginLeft: '0.5em' }} />
      <div className="grid" style={{ marginLeft: '0.20em' }} >
        <DataTable className="col" value={messages} onSelectionChange={e => setSelected(e)} style={{ width: '60em' }} selectionMode="single" scrollable scrollHeight="39.5em" virtualScrollerOptions={{ itemSize: 20 }} responsiveLayout="scroll">
          <Column field="channel" header="Channel"></Column>
          <Column field="payload" header="Payload" ></Column>
        </DataTable>
        <JSONInput
          className="col" 
          placeholder={payload}
          locale={locale}
          colors={{
            string: "#DAA520" // overrides theme colors with whatever color value you want
          }}
          height="40em"
          width="45em"
        />
      </div>
    </div>
  );
}


ReactDOM.render(<App />, document.querySelector("#root"));

For both, we would probably want to simplify the dependencies (no using primereact/icons/flex?). If additional css information is required for the references, I can provide the imported css files too.

Once completed, these extensions should be included in the example application "example" that is brought up from es-compose.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions