Manual Reference Source Test

src/helpers/navigation/AppMenu.js

import AppMenuModel from '../../models/navigation/AppMenu';
import AppMenuService from '../../services/AppMenuService';
import C6Image from '../Image';
import Client from '../../Client';
// import NotificationService from '../services/NotificationService';
import Storage from '../Storage';
import Helper from '../Helper';
import { aggregate } from '../../utilities/ClassUtility';

/**
 * Helper class representing app menu. A app menu redirects the user to different screens and
 * sections of the application.
 */
class AppMenu extends aggregate(AppMenuModel, Helper) {
  /**
   * Helper class representing an single app menu.
   *
   * @param {!Object} [response]              - JSON formatted response of a single menu
   * @param {Number}  response.id             - The id of the app menu
   * @param {String}  response.title          - The title of the app menu
   * @param {String}  response.action         - The action that the devices need to execute when the app menu is tapped.
   *                                            Options are:
   *                                            - about_us
   *                                            - alerts
   *                                            - appointments
   *                                            - ar
   *                                            - arts
   *                                            - badges
   *                                            - brands
   *                                            - breath_assessment
   *                                            - calendar
   *                                            - captured_value_groups
   *                                            - care_circle
   *                                            - companion
   *                                            - companions
   *                                            - comply_scan
   *                                            - contact
   *                                            - container
   *                                            - cost_calculator
   *                                            - data_collection
   *                                            - diamond_club
   *                                            - dynamic_contents
   *                                            - ediary
   *                                            - email
   *                                            - event_report
   *                                            - events
   *                                            - external_url
   *                                            - faq
   *                                            - favorites
   *                                            - flow_process
   *                                            - galleries
   *                                            - give_points
   *                                            - glossary
   *                                            - health_measurements
   *                                            - home
   *                                            - information
   *                                            - key_terms
   *                                            - logout
   *                                            - map
   *                                            - menu
   *                                            - my_trial
   *                                            - news
   *                                            - no_action
   *                                            - offers
   *                                            - outage_map
   *                                            - pain_assessment
   *                                            - payment_locator
   *                                            - personal_center
   *                                            - places
   *                                            - privacy_policy
   *                                            - profile
   *                                            - push_notification
   *                                            - reminders
   *                                            - report_an_outage
   *                                            - rewards
   *                                            - scavenger
   *                                            - send_message
   *                                            - settings
   *                                            - share
   *                                            - social
   *                                            - static_screen
   *                                            - subcategory
   *                                            - tagged_contents
   *                                            - technical_support
   *                                            - terms
   *                                            - tou
   *                                            - tracker
   *                                            - trial
   *                                            - unknown
   *                                            - url
   *                                            - video
   *                                            - video_consult
   *                                            - videos
   * @param {Object}  response.image          - The icon of the app menu
   */
  constructor(json = {}) {
    super(json);
    this.deserializeRelationshipStubs(json);
    this.syncRelationships(json);
    this.updateBadge = new Promise(resolve => resolve(this._badge = null));
    this.processDefaults();

    const _json = json.data || json; // if json api is passed in directly
    const attributes = _json.attributes || _json; // if json api is passed in directly
    if (attributes.image) {
      /** @type {C6Image} */
      this.image = new C6Image(attributes.image);
    }
    this.connectChildren();
  }

  /** @type {String}  - The type */
  static get type() {
    return 'navigation__app_menus';
  }

  /** @type {Any} */
  get actionDetail() {
    return this._relationships.action_detail;
  }

  /** @type {Any} - Types can be data_collection__flow_process | dynamic_content__content_type | data_collection__container | navigation__predefined_screen */
  set actionDetail(actionDetail) {
    /** @type {Any} - Types can be data_collection__flow_process | dynamic_content__content_type | data_collection__container | navigation__predefined_screen */
    this._relationships.action_detail = actionDetail;
  }

  /** @type {String} - Additional information to display near the menu item */
  get badge() {
    return this._badge;
  }

  /** @type {AppMenu[]} */
  get children() {
    return this._children;
  }

  /** @type {FlowContainer} */
  get flowContainer() {
    return this._relationships.flow_container;
  }

  /** @type {FlowContainer} */
  set flowContainer(flowContainer) {
    /** @type {FlowContainer} */
    this._relationships.flow_container = flowContainer;
  }

  /** @type {AppMenu} */
  get parent() {
    return this._relationships.parent;
  }

  /** @type {AppMenu} */
  set parent(parent) {
    /** @type {AppMenu} */
    this._relationships.parent = parent;
  }

  /** @type {PredefinedScreen} */
  get predefinedScreen() {
    return this._relationships.predefined_screen;
  }

  /** @type {PredefinedScreen} */
  set predefinedScreen(predefinedScreen) {
    /** @type {PredefinedScreen} */
    this._relationships.predefined_screen = predefinedScreen;
  }

  /** @type {Promise<String>} - A promise to determine the badge text */
  get updateBadge() {
    return this._updateBadge;
  }

  /** @type {Promise<String>} - A promise to determine the badge text */
  set updateBadge(fn) {
    /** @type {Promise<String>} - A promise to determine the badge text */
    this._updateBadge = fn;
  }

  async connectChildren(appMenus = undefined) {
    this._children = [];
    if (!appMenus) {
      appMenus = await Client.instance.storageUtility.get(this.type, { asArray: true });
    }
    if (appMenus.length) {
      this._children = appMenus.filter(m => m.parent && m.parent.id === this.id);
    } else if (appMenus.id) {
      this._children = [appMenus];
    }
  }

  /**
   * Saves a appMenu (insert if id doesn't exist, update if it does)
   * @return {Promise} - Returns a promise via ajax call.
   *
   * @example
   * import { AppMenu, Client } from 'clinical6';
   *
   * // Removes appMenu from server and local storage
   * const appMenu = new AppMenu({
   *   "id": 1,
   *   "type": "appMenus",
   *   "attributes": {
   *     "udid": "this-is-a-udid-string",
   *     "technology": "ios",
   *     "access_token": "cd68fa04e458d6d1a9d29faec6a329d3",
   *     "push_id": null,
   *     "created_at": "2017-05-19T17:21:26.311Z",
   *     "updated_at": "2017-05-19T17:21:26.311Z",
   *     "app_version": null
   *   }
   * });
   * appMenu.delete();
   *
   * // No longer in storage
   * Client.instance.storageUtility.has('appMenus', { id: 1 });
   * // if cascade parameter pass is true, check that all submenus are also deleted recursively
   */
  async delete(cascade = false) {
    return (new AppMenuService()).delete(this, { cascade });
  }

  /**
   * Process the defaults for the app menu to have correct information.  This will call and
   * store the appropriate values for various modules, such as 'alerts'.
   */
  processDefaults() {
    const self = this;
    const storage = new Storage();
    const { user } = Client.instance;

    this._badge = null;
    switch (this.action) {
      case 'alerts':
        // Setup badge function
        this.updateBadge = storage.notifications.then(
          notifications => (this._badge = Object.values(notifications).filter(a => a.status === 'pending').length)
        ).catch(() => {});

        // Load into storage if it doesn't exist
        if (!storage.notifications) {
          user.getNotifications().then(() => self.updateBadge.then());
        } else {
          self.updateBadge.then();
        }
        break;
      default:
        this.updateBadge = new Promise(resolve => resolve(this._badge = null));
        break;
    }
  }

  /**
   * Saves a appMenu (insert if id doesn't exist, update if it does)
   * @return {Promise<AppMenu>} - Returns a promise via ajax call.
   *
   * @example
   * import { AppMenu, appMenuService } from 'clinical6';
   *
   * // Inserts when id does not exist
   * const appMenu = new AppMenu({
   *   "title": "You are a winner"
   * });
   * appMenu.save();
   *
   * // Updates existing appMenu when id exists
   * appMenuService.get().then(appMenus => appMenus[0].save());
   */
  async save() {
    return (this.id) ? (new AppMenuService()).update(this) : (new AppMenuService()).insert(this);
  }
}

export default AppMenu;