vlocity-dc-global-header/vlocity-dc-global-header.js

/*************************************************************************
 *
 * VLOCITY, INC. CONFIDENTIAL
 * __________________
 *
 *  [2014] - [2020] Vlocity, Inc.
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Vlocity, Inc. and its suppliers,
 * if any. The intellectual and technical concepts contained
 * herein are proprietary to Vlocity, Inc. and its suppliers and may be
 * covered by U.S. and Foreign Patents, patents in process, and are
 * protected by trade secret or copyright law. Dissemination of this
 * information and reproduction, modification or reverse-engineering
 * of this material, is prohibited unless prior written permission
 * is obtained from Vlocity, Inc.
 *
 */
import { LitElement, html } from "lit-element";
import headerTemplate from "./vlocity-dc-global-header-template";
import { digitalCommerceSDKInstance } from "../vlocity-dc-utils/vlocity-dc-sdk-utils";
import VlocityDCBaseComponent from "../vlocity-dc-base-component/vlocity-dc-base-component";
import * as Authentication from "../vlocity-dc-utils/vlocity-dc-custom-authentication/vlocity-dc-authentication-util";
/**
 * @class VlocityDCGlobalHeader
 * @extends {DCBaseComponent} Extends the DCBaseComponent base class
 *
 * @classdesc
 * vlocity-dc-global-header is a component used for rendering a global header which is available accross all components except checkout.
 *
 * @example
 * Sample Usage -
 *
 * Include the component in your template simply by adding vlocity-dc-global-header custom tag
 *
 * <vlocity-dc-global-header></vlocity-dc-global-header>
 *
 *  KEY INFO -
 *
 *  events fired : "vlocity-dc-route-navigation", "vlocity-dc-sign-in" and "vlocity-dc-sign-out"
 *
 *  events registered :
 *
 *     | Event Name                     | Event source component          | Callback Function      | Description                                |
 *     |--------------------------------|---------------------------------|------------------------|--------------------------------------------|
 *     | vlocity-dc-login-complete      | vlocity-dc-sign-in              | loginSuccess()         | Event triggered on login                   |
 *
 *  Dependency - vlocity-dc-global-header is a global component and doesn't have any dependency
 *
 *  Sample with slots -
 *
 *  <vlocity-dc-global-header>
 *      <div slot="{slot_name}">
 *        Custom header HTML elements goes here
 *      </div>
 *  </vlocity-dc-global-header>
 *
 * List of available slots -
 *
 * | Slot names                  | Dynamic     | Description                     | Impact                                 |
 * |-----------------------------|-------------|---------------------------------|----------------------------------------|
 * | dc-global-header            | -           | Wrapper for header elements     | Replaces header elements               |
 *
 */

export default class VlocityDCGlobalHeader extends VlocityDCBaseComponent {
  constructor() {
    super(); // always call super() first in the ctor.
    this.root = this;
    this.template = headerTemplate;
    this.isLoginModalOpen = false;
    this.accountNavigation = false;
    this._isLoggedIn = false;
    this.digitalCommerceSDK =
      digitalCommerceSDKInstance() &&
      digitalCommerceSDKInstance().digitalCommerce;
    this.digitalCommerceTranslation =
      digitalCommerceSDKInstance() &&
      digitalCommerceSDKInstance().digitalCommerceTranslation;
  }
  set isLoggedIn(val) {
    if (val == "true") {
      this._isLoggedIn = true;
    } else if (val == "false") {
      this._isLoggedIn = false;
    } else {
      this._isLoggedIn = val;
    }
  }

  get isLoggedIn() {
    return this._isLoggedIn;
  }

  /**
   *  Properties that will be available in the template binding
   * @readonly
   * @memberof VlocityDCGlobalHeader
   * @static
   */
  static get properties() {
    return {
      menuFlag: Boolean,
      isLoggedIn: Boolean,
      isLoginModalOpen: Boolean,
      loading: Boolean
    };
  }
  connectedCallback() {
    this.loginSuccessEventHandler = {
      result: this.loginSuccess.bind(this)
    };
    this.digitalCommerceSDK &&
      this.digitalCommerceSDK.register(
        "vlocity-dc-login-complete",
        this.loginSuccessEventHandler
      );
    super.connectedCallback();
  }

  render() {
    return this.template(this);
  }

  /**
   * Method to navigate to my accounts
   * @memberof VlocityDCGlobalHeader
   */
  openAccount() {
    if (this.isLoggedIn) {
      const defaultRouteUrl = "/account";
      this.digitalCommerceSDK &&
        this.digitalCommerceSDK.fire("vlocity-dc-route-navigation", "result", {
          data: {},
          defaultRouteUrl: defaultRouteUrl,
          source: "dc-account"
        });
    } else {
      this.accountNavigation = true;
      this.openLoginModal();
    }
  }

  /**
   * Method to open login modal
   * @memberof VlocityDCGlobalHeader
   */
  openLoginModal() {
    this.isLoginModalOpen = true;
  }

  /**
   * Method to close login modal
   * @memberof VlocityDCGlobalHeader
   */
  closeLoginModal() {
    this.isLoginModalOpen = false;
  }

  /**
   * callback function for event vlocity-dc-login-complete
   * @memberof VlocityDCGlobalHeader
   */
  loginSuccess(data) {
    if (data.error) {
      this.loading = false;
    } else {
      this.loading = false;
      this.isLoginModalOpen = false;
      if (data && (data.name || data.email)) {
        this.isLoggedIn = true;
        if (this.accountNavigation) {
          this.openAccount();
        }
      }
    }
  }

  /**
   * Method to signOut the user.
   * @memberof VlocityDCGlobalHeader
   */
  async doSignOut() {
    this.loading = true;
    Authentication.signOut(this.signInDetails)
      .then(async response => {
        let input = this.signOutGetInput(response);
        let udpatedInput = await this.signOutPreHook(input);
        this.signOutPreSDKCalls();
        this.signOutSDKCall(udpatedInput);
      })
      .catch(error => {
        this.signOutHandleFailure(error);
      });
  }
  /**
   * Function to fetch the sign in user sdk call inputs
   * @memberof VlocityDCSignin
   */
  signOutGetInput(input) {
    return Object.assign(this.digitalCommerceSDK.createSignOutUserInput(), {});
  }
  /**
   * A custom function to be used by customers for customisation, any custom action prior to sign out call can be written here
   * @memberof VlocityDCGlobalHeader
   */
  signOutPreHook(input) {
    return Promise.resolve(input);
  }
  /**
   * This function is used to do any changes prior to sdk calls
   * @memberof VlocityDCGlobalHeader
   */
  signOutPreSDKCalls() {
    this.loading = true;
  }

  /**
   * This function is used to do actual sdk calls
   * @memberof VlocityDCGlobalHeader
   */
  signOutSDKCall(input) {
    this.digitalCommerceSDK
      .signOutUser(input)
      .then(response => {
        this.signOutProcessResponse(response);
        this.signOutPostHook(response);
      })
      .catch(error => {
        this.signOutHandleFailure(error);
      });
  }

  /**
   * This function is used to process signOut response
   * @param {object} response - Response Object from SDK call.
   * @memberof VlocityDCGlobalHeader
   */
  signOutProcessResponse(response) {
    this.isLoggedIn = false;
    this.digitalCommerceSDK.fire("vlocity-dc-sign-out", "result", {});
    sessionStorage.setItem("isLoggedIn", false);
    const defaultRouteUrl = "/home";
    this.digitalCommerceSDK.fire("vlocity-dc-route-navigation", "result", {
      data: {},
      defaultRouteUrl: defaultRouteUrl
    });
    this.loading = false;
    sessionStorage.removeItem("rootAssetIds");
    sessionStorage.removeItem("cartContextKey");
  }

  /**
   * A custom function to be used by customers for customisation, any custom action after sign in call can be written here
   * @memberof VlocityDCGlobalHeader
   */
  signOutPostHook(response) {}

  /**
   * A custom function to be used by customers for handling api failures
   * @memberof VlocityDCGlobalHeader
   */
  signOutHandleFailure(error) {
    this.loading = false;
    console.error("Signout failed with error ", error);
  }

  disconnectedCallback() {
    this.digitalCommerceSDK &&
      this.digitalCommerceSDK.unregister(
        "vlocity-dc-login-complete",
        this.loginSuccessEventHandler
      );
  }

  /**
   * Method to initiate login/signup SDK call.
   * @memberof VlocityDCGlobalHeader
   */
  initLogin() {
    this.loading = true;
    this.digitalCommerceSDK &&
      this.digitalCommerceSDK.fire("vlocity-dc-sign-in", "result", {});
  }
}

customElements.define("vlocity-dc-global-header", VlocityDCGlobalHeader);