diff --git a/client/luigi-client-wc-docu-mixin.js b/client/luigi-client-wc-docu-mixin.js
new file mode 100644
index 0000000000..e9c52d4839
--- /dev/null
+++ b/client/luigi-client-wc-docu-mixin.js
@@ -0,0 +1,62 @@
+/**
+ *
+ * Publish an event that can be listened to from the container host.
+ *
+ * Similar to {@link luigi-client-api.md#sendCustomMessage sendCustomMessage} but for WebComponent based microfrontends only.
+ *
+ * @param {CustomEvent} event Custom event to be published
+ * @memberof Lifecycle
+ *
+ * @example
+ * // case 1: publish an event from a WC based microfrontend
+ *
+ * // wcComponent.js
+ * // sending a message to parent host
+ * this.LuigiClient.publishEvent(new CustomEvent('sendSomeMsg', { detail: 'My own message' }));
+ *
+ * // host.html
+ * myContainer.addEventListener('custom-message', event => {
+ * console.log('My custom message from the microfrontend', event.detail.data);
+ * }
+ *
+ * // case 2: publish an event from a compound microfrontend
+ *
+ * // secondChild.js
+ * // Set the custom event name = 'sendInput' and
+ * // send a message to its parent (main.html) and sibling (firstChild.js)
+ * this.LuigiClient.publishEvent(new CustomEvent('sendInput', { detail: 'My own message' }));
+ *
+ * // main.html
+ * myContainer.addEventListener('custom-message', event => {
+ * console.log('My custom message from microfrontend', event.detail.data);
+ * }
+ *
+ * // Note: eventListeners.name must match CustomEvent name above
+ * // eventListeners.source = input1 = id of secondChild.js, which is where the message being sent from
+ * compoundConfig = {
+ * ...
+ * children: [
+ * {
+ * viewUrl: 'firstChild.js'
+ * ...
+ * eventListeners: [
+ * {
+ * source: 'input1',
+ * name: 'sendInput',
+ * action: 'update',
+ * dataConverter: data => {
+ * console.log(
+ * 'dataConverter(): Received Custom Message from "input1" MF ' + data
+ * );
+ * return 'new text: ' + data;
+ * }
+ * }
+ * ]
+ * },
+ * {
+ * viewUrl: 'secondChild.js',
+ * id: 'input1',
+ * }
+ *
+ */
+export function publishEvent(event) {}
diff --git a/container/cypress/e2e/test-app/compound/wc-compound-container.cy.js b/container/cypress/e2e/test-app/compound/wc-compound-container.cy.js
index 63d4f06327..a934d8fe86 100644
--- a/container/cypress/e2e/test-app/compound/wc-compound-container.cy.js
+++ b/container/cypress/e2e/test-app/compound/wc-compound-container.cy.js
@@ -174,5 +174,26 @@ describe('Compound Container Tests', () => {
cy.get('#defer-init-flag').should('exist');
});
+
+ it('LuigiClient API publishEvent', () => {
+ cy.on('window:alert', stub);
+
+ // Set up a spy on console.log
+ cy.window().then(win => {
+ cy.spy(win.console, 'log').as('consoleLogSpy');
+ });
+
+ cy.get(containerSelector)
+ .shadow()
+ .contains('Publish event')
+ .click()
+ .then(() => {
+ expect(stub.getCall(0)).to.be.calledWith('sendInput');
+ cy.get('@consoleLogSpy').should(
+ 'be.calledWith',
+ 'dataConverter(): Received Custom Message from "input1" MF My own event data'
+ );
+ });
+ });
});
});
diff --git a/container/cypress/e2e/test-app/wc/wc-container.cy.js b/container/cypress/e2e/test-app/wc/wc-container.cy.js
index 0ef0ebdf0d..5e1eb4c1f1 100644
--- a/container/cypress/e2e/test-app/wc/wc-container.cy.js
+++ b/container/cypress/e2e/test-app/wc/wc-container.cy.js
@@ -137,12 +137,23 @@ describe('Web Container Test', () => {
.find('#customMessageDiv')
.should('have.text', 'Received Custom Message: ');
- cy.get('#sendCustomMessageBtn')
- .click()
+ cy.get('#sendCustomMessageBtn').click();
cy.get(containerSelector)
.shadow()
.find('#customMessageDiv')
.should('have.text', 'Received Custom Message: cool custom Message');
+ });
+
+ it('receive custom message from WC', () => {
+ cy.on('window:alert', stub);
+
+ cy.get('[data-test-id="luigi-client-api-test-01"]')
+ .shadow()
+ .contains('Publish event')
+ .click()
+ .then(() => {
+ expect(stub.getCall(0)).to.be.calledWith('My Custom Message from Microfrontend');
});
+ });
});
});
diff --git a/container/src/services/webcomponents.service.ts b/container/src/services/webcomponents.service.ts
index 0461c1f6b6..a9d9587c3b 100644
--- a/container/src/services/webcomponents.service.ts
+++ b/container/src/services/webcomponents.service.ts
@@ -277,6 +277,7 @@ export class WebComponentService {
},
publishEvent: ev => {
if (eventBusElement && eventBusElement.eventBus) {
+ // compound component use case only
eventBusElement.eventBus.onPublishEvent(ev, nodeId, wc_id);
}
const payload = {
diff --git a/container/test-app/compound/compoundClientAPI.html b/container/test-app/compound/compoundClientAPI.html
index 6eccf82165..6dc5ee12fe 100644
--- a/container/test-app/compound/compoundClientAPI.html
+++ b/container/test-app/compound/compoundClientAPI.html
@@ -62,9 +62,11 @@
import MFEventID from '../bundle.js';
const compoundContainer = document.getElementById('dashboard');
+
compoundContainer.addEventListener(MFEventID.CUSTOM_MESSAGE, e => {
- console.log('Publish Event', e.detail);
+ console.log('CUSTOM_MESSAGE Listener picked up: ', e.detail);
});
+
compoundContainer.compoundConfig = {
renderer: {
use: 'grid',
@@ -103,6 +105,9 @@
name: 'sendInput',
action: 'update',
dataConverter: data => {
+ console.log(
+ 'dataConverter(): Received Custom Message from "input1" MF ' + data
+ );
return 'new text: ' + data;
}
}
@@ -168,7 +173,6 @@
}
);
compoundContainer.addEventListener(MFEventID.CUSTOM_MESSAGE, event => {
- console.log('Custom Event', event);
if (event.detail.id !== 'timer') {
alert(event.detail.id);
}
diff --git a/container/test-app/compound/helloWorldWC.js b/container/test-app/compound/helloWorldWC.js
index 846e741773..8194bd83f0 100644
--- a/container/test-app/compound/helloWorldWC.js
+++ b/container/test-app/compound/helloWorldWC.js
@@ -17,7 +17,7 @@ export default class extends HTMLElement {
current_locale.innerHTML = '';
const templateBtn2 = document.createElement('template');
- templateBtn2.innerHTML = '';
+ templateBtn2.innerHTML = '';
const addNodeParamsBtn = document.createElement('template');
addNodeParamsBtn.innerHTML = '';
@@ -151,20 +151,22 @@ export default class extends HTMLElement {
});
}
});
- this._shadowRoot.querySelector('.button2').addEventListener('click', () => {
+
+ this.$publishEventBtn = this._shadowRoot.querySelector('#publishEvent');
+ this.$publishEventBtn.addEventListener('click', () => {
if (this.LuigiClient) {
- this.LuigiClient.publishEvent(new CustomEvent('btnClick'));
+ this.LuigiClient.publishEvent(new CustomEvent('sendInput', { detail: 'My own event data' }));
}
});
- this.$button2 = this._shadowRoot.querySelector('#addNodeParams');
- this.$button2.addEventListener('click', () => {
+ this.$addNodeParamsBtn = this._shadowRoot.querySelector('#addNodeParams');
+ this.$addNodeParamsBtn.addEventListener('click', () => {
if (this.LuigiClient) {
this.LuigiClient.addNodeParams({ Luigi: 'rocks' }, true);
}
});
- this.$button3 = this._shadowRoot.querySelector('#getNodeParams');
- this.$button3.addEventListener('click', () => {
+ this.$getNodeParamsBtn = this._shadowRoot.querySelector('#getNodeParams');
+ this.$getNodeParamsBtn.addEventListener('click', () => {
if (this.LuigiClient) {
let nodeParams = this.LuigiClient.getNodeParams(false);
this.LuigiClient.uxManager().showAlert({
diff --git a/container/test-app/wc/clientAPI.html b/container/test-app/wc/clientAPI.html
index 186331bdac..c9cd0ae3fa 100644
--- a/container/test-app/wc/clientAPI.html
+++ b/container/test-app/wc/clientAPI.html
@@ -10,7 +10,9 @@
component based microfrontend
-
+
@@ -49,7 +51,7 @@
defer-init="true"
>
-
+
@@ -70,10 +72,14 @@
deferInitContainer.init();
});
// document.querySelector('luigi-container');
- const container = document.querySelector('[data-test-id="luigi-client-api-test-01"]')
+ const container = document.querySelector(
+ '[data-test-id="luigi-client-api-test-01"]'
+ );
const sendCustomMsgBtn = document.getElementById('sendCustomMessageBtn');
sendCustomMsgBtn.addEventListener('click', () => {
- container.sendCustomMessage('custom-message-id', {dataToSend: 'cool custom Message'});
+ container.sendCustomMessage('custom-message-id', {
+ dataToSend: 'cool custom Message'
+ });
});
[...document.querySelectorAll('luigi-container')].forEach(luigiContainer => {
@@ -96,9 +102,8 @@
}
);
luigiContainer.addEventListener(MFEventID.CUSTOM_MESSAGE, event => {
- console.log('Custom Event', event);
if (event.detail.id !== 'timer') {
- alert(event.detail.id);
+ alert(event.detail.data);
}
});
diff --git a/container/test-app/wc/helloWorldWC.js b/container/test-app/wc/helloWorldWC.js
index 2618d59a0f..88cd9aaffd 100644
--- a/container/test-app/wc/helloWorldWC.js
+++ b/container/test-app/wc/helloWorldWC.js
@@ -14,7 +14,7 @@ export default class extends HTMLElement {
templateBtn.innerHTML = '';
const templateBtn2 = document.createElement('template');
- templateBtn2.innerHTML = '';
+ templateBtn2.innerHTML = '';
const addNodeParamsBtn = document.createElement('template');
addNodeParamsBtn.innerHTML = '';
@@ -90,7 +90,6 @@ export default class extends HTMLElement {
const customMessageDiv = document.createElement('template');
customMessageDiv.innerHTML = '
Received Custom Message:
';
-
this._shadowRoot = this.attachShadow({
mode: 'open',
@@ -141,20 +140,21 @@ export default class extends HTMLElement {
});
}
});
- this._shadowRoot.querySelector('.button2').addEventListener('click', () => {
+ this._shadowRoot.querySelector('#publishEvent').addEventListener('click', () => {
if (this.LuigiClient) {
- this.LuigiClient.publishEvent(new CustomEvent('btnClick'));
+ // send a custom event (similar to sendCustomMessage)
+ this.LuigiClient.publishEvent(new CustomEvent('sendMSG', { detail: 'My Custom Message from Microfrontend' }));
}
});
- this.$button2 = this._shadowRoot.querySelector('#addNodeParams');
- this.$button2.addEventListener('click', () => {
+ this.$addNodeParamsBtn = this._shadowRoot.querySelector('#addNodeParams');
+ this.$addNodeParamsBtn.addEventListener('click', () => {
if (this.LuigiClient) {
this.LuigiClient.addNodeParams({ Luigi: 'rocks' }, true);
}
});
- this.$button3 = this._shadowRoot.querySelector('#getNodeParams');
- this.$button3.addEventListener('click', () => {
+ this.$getNodeParamsBtn = this._shadowRoot.querySelector('#getNodeParams');
+ this.$getNodeParamsBtn.addEventListener('click', () => {
if (this.LuigiClient) {
let nodeParams = this.LuigiClient.getNodeParams(false);
this.LuigiClient.uxManager().showAlert({
@@ -313,13 +313,12 @@ export default class extends HTMLElement {
}
});
- this.addEventListener('custom-message-id', (event) => {
- console.log('custom message received: ', event.detail)
+ this.addEventListener('custom-message-id', event => {
+ console.log('custom message received: ', event.detail);
const customMessageDiv = this._shadowRoot.querySelector('#customMessageDiv');
customMessageDiv.textContent = `Received Custom Message: ${event.detail.dataToSend}`;
- customMessageDiv.style = "color: red;";
- })
-
+ customMessageDiv.style = 'color: red;';
+ });
}
get context() {
diff --git a/docs/luigi-client-api.md b/docs/luigi-client-api.md
index 740410c17c..a13e9351bb 100644
--- a/docs/luigi-client-api.md
+++ b/docs/luigi-client-api.md
@@ -33,6 +33,72 @@ This document outlines the features provided by the Luigi Client API. It covers
Use the functions and parameters to define the Lifecycle of listeners, navigation nodes, and Event data.
+#### publishEvent
+
+
+
+Publish an event that can be listened to from the container host.
+
+Similar to [sendCustomMessage](luigi-client-api.md#sendCustomMessage) but for WebComponent based microfrontends only.
+
+##### Parameters
+
+* `event` **[CustomEvent](https://developer.mozilla.org/docs/Web/API/CustomEvent/CustomEvent)** Custom event to be published
+
+##### Examples
+
+```javascript
+// case 1: publish an event from a WC based microfrontend
+
+// wcComponent.js
+// sending a message to parent host
+this.LuigiClient.publishEvent(new CustomEvent('sendSomeMsg', { detail: 'My own message' }));
+
+// host.html
+myContainer.addEventListener('custom-message', event => {
+ console.log('My custom message from the microfrontend', event.detail.data);
+}
+
+// case 2: publish an event from a compound microfrontend
+
+// secondChild.js
+// Set the custom event name = 'sendInput' and
+// send a message to its parent (main.html) and sibling (firstChild.js)
+this.LuigiClient.publishEvent(new CustomEvent('sendInput', { detail: 'My own message' }));
+
+// main.html
+myContainer.addEventListener('custom-message', event => {
+ console.log('My custom message from microfrontend', event.detail.data);
+}
+
+// Note: eventListeners.name must match CustomEvent name above
+// eventListeners.source = input1 = id of secondChild.js, which is where the message being sent from
+compoundConfig = {
+ ...
+ children: [
+ {
+ viewUrl: 'firstChild.js'
+ ...
+ eventListeners: [
+ {
+ source: 'input1',
+ name: 'sendInput',
+ action: 'update',
+ dataConverter: data => {
+ console.log(
+ 'dataConverter(): Received Custom Message from "input1" MF ' + data
+ );
+ return 'new text: ' + data;
+ }
+ }
+ ]
+ },
+ {
+ viewUrl: 'secondChild.js',
+ id: 'input1',
+ }
+```
+
#### isLuigiClientInitialized
Check if LuigiClient is initialized
diff --git a/scripts/package.json b/scripts/package.json
index 3d6405fab9..fbfc9a5ca5 100644
--- a/scripts/package.json
+++ b/scripts/package.json
@@ -10,7 +10,7 @@
"docu:container:generate:container-api": "documentation readme ../container/typings/LuigiContainer.svelte.d.ts --parse-extension ts -f md --readme-file=../docs/luigi-container-api.md --section=\"API Reference\" --markdown-toc=false --quiet --github false",
"docu:container:generate:compound-container-api": "documentation readme ../container/typings/LuigiCompoundContainer.svelte.d.ts --parse-extension ts -f md --readme-file=../docs/luigi-compound-container-api.md --section=\"API Reference\" --markdown-toc=false --quiet --github false",
"docu:client": "npm run docu:client:validate && npm run docu:client:generate:section",
- "docu:client:generate:section": "documentation readme ../client/src/luigi-client.js -f md --readme-file=../docs/luigi-client-api.md --section=\"API Reference\" --markdown-toc=false --quiet --github false",
+ "docu:client:generate:section": "documentation readme ../client/src/luigi-client.js ../client/luigi-client-wc-docu-mixin.js -f md --readme-file=../docs/luigi-client-api.md --section=\"API Reference\" --markdown-toc=false --quiet --github false",
"docu:client:validate": "documentation lint ../client/src/luigi-client.js",
"docu:core": "npm run docu:core:validate && npm run docu:core:generate:sections",
"docu:core:validate": "documentation lint --shallow ../core/src/core-api/config.js ../core/src/core-api/elements.js ../core/src/core-api/auth.js ../core/src/core-api/navigation.js ../core/src/core-api/i18n.js ../core/src/core-api/custom-messages.js ../core/src/core-api/ux.js ../core/src/core-api/globalsearch.js ../core/src/core-api/theming.js ../core/src/core-api/featuretoggles.js",