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;