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;