Manual Reference Source Test

src/helpers/cohort/Cohort.js

import { deprecate } from 'core-decorators'; // eslint-disable-line
import CohortAssignment from './CohortAssignment';
import CohortModel from '../../models/cohort/Cohort';
import Helper from '../Helper';
import { aggregate } from '../../utilities/ClassUtility';
import { serviceFactory } from '../../utilities/factories/ServiceFactory';

/**
 * Helper class representing a cohort.
 *
 * @extends {CohortModel}
 * @extends {Helper}
 *
 * @example
 * // To get a list of Cohorts use clinical6.get
 * import { clinical6, Cohort } from 'clinical6';
 * clinical6.get(Cohort).then(c => console.log(c));
 *
 * // To get a single cohort, you can also use clinical6
 * clinical6.get({ id: 5, type: 'cohorts'});
 *
 * // To save or insert, you can either use the .save() capability or clinical6
 * myCohort.save(); // insert if no id, save if id
 * clinical6.insert(new Cohort({...}));
 * clinical6.update(myCohort);
 *
 * // To delete you can use the .delete() capability or clinical6
 * myCohort.delete();
 * clinical6.delete(myCohort);
 */
class Cohort extends aggregate(CohortModel, Helper) {
  /**
   * Constructor for helper class representing a Cohort
   *
   * @param {Object} json - json api response from server
   */
  constructor(json = {}) {
    super(json);
    /** @type {CohortAssignment[]} */
    this._assignments = [];
    /** @type {User[]} */
    this._users = [];
  }

  /** @type {CohortAssignment[]} */
  get assignments() {
    return this._assignments;
  }

  /** @type {CohortAssignment[]} */
  set assignments(assignments) {
    this._assignments = assignments;
  }

  /** @type {User[]} */
  get users() {
    return this._users;
  }

  /** @type {User[]} */
  set users(users) {
    this._users = users;
  }

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

  /**
   * This will create a CohortAssignment and save it to the server based on this current cohort and the user parameter
   *
   * @param {User} user                   - The user to be added to this cohort
   * @return {Promise<CohortAssignment}   - Returns the cohort assignment
   *
   * @example
   * import { clinical6, User, Cohort } from 'clinical6';
   * const cohorts = await clinical6.get(Cohort);
   * const user = new User({...}); // some new user
   * const assignment = await cohorts[0].addUser(user);
   */
  async addUser(user) {
    let assignment = new CohortAssignment();
    assignment.cohort = this;
    assignment.user = user;
    this.users.push(user);
    assignment = await assignment.save();
    this.assignments.push(assignment);
    return assignment;
  }

  /**
   * Deletes a cohort
   * @return {Promise} - Returns a promise via ajax call.
   *
   * @example
   * import { Cohort, Client } from 'clinical6';
   *
   * // Removes cohort from server and local storage
   * const cohort = new Cohort({...});
   * cohort.delete();
   *
   * // No longer in storage
   * Client.instance.storageUtility.has('cohorts', { id: 1 });
   */
  delete() {
    const service = serviceFactory.get(this.type);
    return service.delete(this);
  }

  /**
   * Gets the list of users after calling this.getAssignments()
   * @return {Promise<Users[]>} - Promise returning an array of users
   *
   * @example
   * import { clinical6, Cohort } from 'clinical6';
   * const cohorts = await clinical6.get(Cohort);
   * const users = await cohorts[0].getUsers();
   * console.log(users);
   */
  async getUsers() {
    return (await this.getAssignments()).map(a => a.user);
  }

  /**
   * Gets the cohort assignment associated to this cohort.
   *
   * @param  {Object} [params]            - Parameters used to get information from server
   * @param  {Number} [params.id]         - Id to get data from the server
   * @param  {String} [params.type]       - Type to be used for storage
   * @param  {Object} [params.filters]    - Filters to be used for get
   * @param  {String} [options]           - Modify the nature of the call and response
   * @param  {String} [options.url]       - Override the url for this call
   * @param  {String} [options.cacheMode] - Override the caching method for this call
   * @return {Promise}                    - Promise with data (array or object)
   *
   * @example
   * import { Cohort, clinical6 } from 'clinical6';
   * const cohort = new Cohort({ id: 23 });
   * cohort.getAssignments({ id: 5 });
   *
   * // Combined with clinical6.get
   * clinical6.get(Cohort).then(cohorts => { cohorts[0].getAssignments() });
   */
  async getAssignments(params = {}, options = {}) {
    const service = serviceFactory.get(this.type);
    const assignment = { type: CohortAssignment.type };
    if (params.id) {
      assignment.id = params.id;
    } else if (params.filters) {
      assignment.filters = params.filters;
    }
    const response = await service.getChildren(this, assignment, options);
    if (Array.isArray(response)) {
      this.assignments = response;
      this.users = this.assignments.map(a => a.user);
    } else if (params.id) {
      // if the developer asks for one assignment given one id, return as just an object
      this.assignments = response;
      this.users = response.user;
    } else {
      // otherwise, there is just one response, make it an array
      this.assignments = [response];
      this.users = [response.user];
    }
    return this.assignments;
  }

  /**
   * Removes an assignment from a Cohort.
   *
   * @param {CohortAssignment|User} obj - Object that is to be removed from current Cohort.
   * @return {Promise}                  - Promise likely with an empty string or error
   *
   * @example
   * import { clinical6, User, Cohort } from 'clinical6';
   * const cohorts = await clinical6.get(Cohort);
   * const user = new User({...}); // some new user
   * const assignment = await cohorts[0].removeUser(user);
   */
  async removeUser(obj) {
    let assignment;
    if (obj.type === 'users' || obj.type === 'mobile_users') {
      assignment = (await this.getAssignments()).find(a => (a.user.id === obj.id));
    } else if (obj.type === 'cohort_assignments') {
      assignment = obj;
    } else {
      throw new Error('Cohort.removeUser cannot delete: obj is not an assignment or user');
    }
    return assignment.delete();
  }

  /**
   * Saves a cohort (insert if id doesn't exist, update if it does)
   * @return {Promise<Cohort>} - Returns a promise via ajax call.
   *
   * @example
   * import { Cohort, clinical6 } from 'clinical6';
   *
   * // Inserts new role (no existing id)
   * const cohort = new Cohort({
   *   "type": "cohorts",
   *   "attributes": {
   *       "name": "name",
   *       "cohort_type": "static"
   *   }
   * });
   * cohort.save();
   *
   * // Updates existing cohort(has existing id)
   * clinical6.get(Cohort).then(cohorts => cohorts[0].save());
   */
  async save() {
    const service = serviceFactory.get(this.type);
    return (this.id) ? service.update(this) : service.insert(this);
  }
}

export default Cohort;