Repository: SAP/luigi (js)

Issue:
add "setDirtyStatus" to wc client uxManager
... and dispatch corresponding event in container and compoundContainer

Pull request description:
Adds setDirtyStatus to WC client
**Description**

Changes proposed in this pull request:

- adds setDirtyStatus to WC client

**Related issue(s)**

Resolves #4220 


Patch:
diff --git a/container/src/services/webcomponents.service.ts b/container/src/services/webcomponents.service.ts
index be678fdb..de05c5af 100644
--- a/container/src/services/webcomponents.service.ts
+++ b/container/src/services/webcomponents.service.ts
@@ -337,6 +337,9 @@ export class WebComponentService {
           setDocumentTitle: (title) => {
             this.dispatchLuigiEvent(Events.SET_DOCUMENT_TITLE_REQUEST, title);
           },
+          setDirtyStatus: (isDirty: boolean) => {
+            this.dispatchLuigiEvent(Events.SET_DIRTY_STATUS_REQUEST, { dirty: isDirty });
+          },
           setCurrentLocale: (locale: string) => {
             if (locale) {
               this.dispatchLuigiEvent(Events.SET_CURRENT_LOCALE_REQUEST, { currentLocale: locale });


Test patch:
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 c9fc1433..482f4b49 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
@@ -81,6 +81,18 @@ describe('Compound Container Tests', () => {
         });
     });
 
+    it('LuigiClient API - setDirtyStatus', () => {
+      cy.on('window:alert', stub);
+
+      cy.get(containerSelector)
+        .shadow()
+        .contains('setDirtyStatus')
+        .click()
+        .then(() => {
+          expect(stub.getCall(0)).to.be.calledWith('LuigiClient.uxManager().setDirtyStatus()=true');
+        });
+    });
+
     it('LuigiClient API - getClientPermissions', () => {
       cy.on('window:alert', stub);
 
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 de27cfc7..90cdb9f4 100644
--- a/container/cypress/e2e/test-app/wc/wc-container.cy.js
+++ b/container/cypress/e2e/test-app/wc/wc-container.cy.js
@@ -35,6 +35,18 @@ describe('Web Container Test', () => {
         });
     });
 
+    it('setDirtyStatus', () => {
+      cy.on('window:alert', stub);
+
+      cy.get(containerSelector)
+        .shadow()
+        .contains('setDirtyStatus')
+        .click()
+        .then(() => {
+          expect(stub.getCall(0)).to.be.calledWith('LuigiClient.uxManager().setDirtyStatus()=true');
+        });
+    });
+
     it('setCurrentLocale', () => {
       cy.on('window:alert', stub);
 
diff --git a/container/test-app/compound/compoundClientAPI.html b/container/test-app/compound/compoundClientAPI.html
index 813ef355..8322047a 100644
--- a/container/test-app/compound/compoundClientAPI.html
+++ b/container/test-app/compound/compoundClientAPI.html
@@ -263,6 +263,10 @@
       compoundContainer.addEventListener(MFEventID.SET_ANCHOR_LINK_REQUEST, (event) => {
         console.log('anchor', event.detail);
       });
+      compoundContainer.addEventListener(MFEventID.SET_DIRTY_STATUS_REQUEST, (event) => {
+        console.log('dirty', event.detail);
+        alert('LuigiClient.uxManager().setDirtyStatus()=' + event.detail.dirty);
+      });
       compoundContainer.addEventListener(
         MFEventID.SET_CURRENT_LOCALE_REQUEST,
         (event) => {
diff --git a/container/test-app/compound/helloWorldWC.js b/container/test-app/compound/helloWorldWC.js
index e21ee35c..5a58104a 100644
--- a/container/test-app/compound/helloWorldWC.js
+++ b/container/test-app/compound/helloWorldWC.js
@@ -64,6 +64,9 @@ export default class extends HTMLElement {
     const getDirtyStatusBtn = document.createElement('template');
     getDirtyStatusBtn.innerHTML = '<button id="getDirtyStatus">getDirtyStatus</button>';
 
+    const setDirtyStatusBtn = document.createElement('template');
+    setDirtyStatusBtn.innerHTML = '<button id="setDirtyStatus">setDirtyStatus</button>';
+
     const retrieveContextValueBtn = document.createElement('template');
     retrieveContextValueBtn.innerHTML = '<button id="retrieveContextValue">retrieveContextValue</button>';
 
@@ -137,6 +140,7 @@ export default class extends HTMLElement {
     this._shadowRoot.appendChild(getFeatureToggleListBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(getThemeBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(getDirtyStatusBtn.content.cloneNode(true));
+    this._shadowRoot.appendChild(setDirtyStatusBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(retrieveContextValueBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(uxManagerMultipleRequestsBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(linkManagerChainedFunctionsRequestsBtn.content.cloneNode(true));
@@ -325,6 +329,11 @@ export default class extends HTMLElement {
       });
     });
 
+    this.$setDirtyStatusBtn = this._shadowRoot.querySelector('#setDirtyStatus');
+    this.$setDirtyStatusBtn.addEventListener('click', () => {
+      this.LuigiClient.uxManager().setDirtyStatus(true);
+    });
+
     this.$retrieveContextValueBtn = this._shadowRoot.querySelector('#retrieveContextValue');
     this.$retrieveContextValueBtn.addEventListener('click', () => {
       this.LuigiClient.uxManager().showAlert({
diff --git a/container/test-app/wc/clientAPI.html b/container/test-app/wc/clientAPI.html
index bed88e60..74dd8317 100644
--- a/container/test-app/wc/clientAPI.html
+++ b/container/test-app/wc/clientAPI.html
@@ -197,6 +197,10 @@
         luigiContainer.addEventListener(MFEventID.SET_ANCHOR_LINK_REQUEST, (event) => {
           console.log('anchor', event.detail);
         });
+        luigiContainer.addEventListener(MFEventID.SET_DIRTY_STATUS_REQUEST, (event) => {
+          console.log('dirty', event.detail);
+          alert('LuigiClient.uxManager().setDirtyStatus()=' + event.detail.dirty);
+        });
         luigiContainer.addEventListener(MFEventID.SET_CURRENT_LOCALE_REQUEST, (event) => {
           console.log('locale', event.detail);
           alert(
diff --git a/container/test-app/wc/helloWorldWC.js b/container/test-app/wc/helloWorldWC.js
index fdc2274a..8f4518a6 100644
--- a/container/test-app/wc/helloWorldWC.js
+++ b/container/test-app/wc/helloWorldWC.js
@@ -55,6 +55,9 @@ export default class extends HTMLElement {
     const getDirtyStatusBtn = document.createElement('template');
     getDirtyStatusBtn.innerHTML = '<button id="getDirtyStatus">getDirtyStatus</button>';
 
+    const setDirtyStatusBtn = document.createElement('template');
+    setDirtyStatusBtn.innerHTML = '<button id="setDirtyStatus">setDirtyStatus</button>';
+
     const updateContextBtn = document.createElement('template');
     updateContextBtn.innerHTML = '<button id="updateContext">updateContext</button>';
 
@@ -135,6 +138,7 @@ export default class extends HTMLElement {
     this._shadowRoot.appendChild(getUserSettingsBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(getAnchorBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(getDirtyStatusBtn.content.cloneNode(true));
+    this._shadowRoot.appendChild(setDirtyStatusBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(updateContextBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(uxManagerMultipleRequestsBtn.content.cloneNode(true));
     this._shadowRoot.appendChild(linkManagerChainedFunctionsRequestsBtn.content.cloneNode(true));
@@ -292,6 +296,11 @@ export default class extends HTMLElement {
       });
     });
 
+    this.$setDirtyStatusBtn = this._shadowRoot.querySelector('#setDirtyStatus');
+    this.$setDirtyStatusBtn.addEventListener('click', () => {
+      this.LuigiClient.uxManager().setDirtyStatus(true);
+    });
+
     this.$updateContextBtn = this._shadowRoot.querySelector('#updateContext');
     this.$updateContextBtn.addEventListener('click', () => {
       this.LuigiClient.uxManager().showAlert({
diff --git a/container/test/services/webcomponents.service.spec.ts b/container/test/services/webcomponents.service.spec.ts
index 0d879296..9e0e67f8 100644
--- a/container/test/services/webcomponents.service.spec.ts
+++ b/container/test/services/webcomponents.service.spec.ts
@@ -756,29 +756,30 @@ describe('createClientAPI', () => {
       expect(result).toEqual('Title');
     });
 
-    it('test uxManager getDirtyStatus', () => {
+    it.each([true, false])('test uxManager getDirtyStatus', (value) => {
       // mock and spy on data/functions
       service.thisComponent = document.createElement('div');
-      service.thisComponent.dirtyStatus = true;
+      service.thisComponent.dirtyStatus = value;
 
       // act
       const clientAPI = service.createClientAPI(undefined, 'nodeId', 'wc_id', 'component');
       const result = clientAPI.uxManager().getDirtyStatus();
 
       // assert
-      expect(result).toEqual(true);
+      expect(result).toEqual(value);
     });
 
-    it('test uxManager getDirtyStatus', () => {
-      // mock and spy on data/functions
-      service.thisComponent = document.createElement('div');
+    it.each([true, false])('test uxManager setDirtyStatus', (value) => {
+      // mock and spy on functions
+      service.containerService.dispatch = jest.fn();
+      const dispatchEventSpy = jest.spyOn(service, 'dispatchLuigiEvent');
 
       // act
       const clientAPI = service.createClientAPI(undefined, 'nodeId', 'wc_id', 'component');
-      const result = clientAPI.uxManager().getDirtyStatus();
+      clientAPI.uxManager().setDirtyStatus(value);
 
       // assert
-      expect(result).toEqual(false);
+      expect(dispatchEventSpy).toHaveBeenCalledWith(Events.SET_DIRTY_STATUS_REQUEST, { dirty: value });
     });
 
     it('test uxManager setCurrentLocale', () => {