import _ from 'lodash';
import { Meteor } from 'meteor/meteor';
import SimpleSchema from 'simpl-schema';
import BaseProfileCollection, { defaultProfilePicture } from './BaseProfileCollection';
import { Users } from './UserCollection';
import { Interests } from '../interest/InterestCollection';
import { CareerGoals } from '../career/CareerGoalCollection';
import { Slugs } from '../slug/SlugCollection';
import { ROLE } from '../role/Role';
import { ProfileDefine, ProfileUpdate } from '../../typings/radgrad';
import { FavoriteInterests } from '../favorite/FavoriteInterestCollection';
import { FavoriteCareerGoals } from '../favorite/FavoriteCareerGoalCollection';
/**
* Represents a Admin Profile.
* @extends api/user.BaseProfileCollection
* @memberOf api/user
*/
class AdminProfileCollection extends BaseProfileCollection {
constructor() {
super('AdminProfile', new SimpleSchema({}));
}
/**
* Defines the profile associated with an Admin and the associated Meteor account.
* @param username The username string associated with this profile, which should be an email.
* @param firstName The first name.
* @param lastName The last name.
* @param picture The URL to their picture. (optional, defaults to a default picture.)
* @param website The URL to their personal website (optional).
* @param interests An array of interests. (optional)
* @param careerGoals An array of career goals. (optional)
* @throws { Meteor.Error } If username has been previously defined, or if any interests or careerGoals are invalid.
* @return { String } The docID of the AdminProfile.
*/
public define({ username, firstName, lastName, picture = defaultProfilePicture, website, interests,
careerGoals, retired = false }: ProfileDefine) {
if (Meteor.isServer) {
const user = Meteor.users.findOne({ username });
// console.log(`AdminProfile.define ${user}`);
if (!user) {
const role = ROLE.ADMIN;
Slugs.define({ name: username, entityName: this.getType() });
const profileID = this.collection.insert({
username, firstName, lastName, role, picture, website, userID: this.getFakeUserId(), retired,
});
const userID = Users.define({ username, role });
this.collection.update(profileID, { $set: { userID } });
if (interests) {
interests.forEach((interest) => FavoriteInterests.define({ interest, username }));
}
if (careerGoals) {
careerGoals.forEach((careerGoal) => FavoriteCareerGoals.define({ careerGoal, username }));
}
return profileID;
}
return this.collection.findOne({ username })._id;
}
return undefined;
}
/**
* Updates the AdminProfile.
* You cannot change the username or role once defined.
* @param docID the id of the AdminProfile.
*/
public update(docID, { firstName, lastName, picture, website, interests, careerGoals, retired, courseExplorerFilter, opportunityExplorerSortOrder }: ProfileUpdate) {
this.assertDefined(docID);
const updateData = {};
this.updateCommonFields(updateData, { firstName, lastName, picture, website, retired, courseExplorerFilter, opportunityExplorerSortOrder });
this.collection.update(docID, { $set: updateData });
const profile = this.findDoc(docID);
const username = profile.username;
if (interests) {
FavoriteInterests.removeUser(username);
interests.forEach((interest) => FavoriteInterests.define({ interest, username }));
}
if (careerGoals) {
FavoriteCareerGoals.removeUser(username);
careerGoals.forEach((careerGoal) => FavoriteCareerGoals.define({ careerGoal, username }));
}
}
/**
* Implementation of assertValidRoleForMethod. Asserts that userId is logged in as an Admin or Admin.
* This is used in the define, update, and removeIt Meteor methods associated with each class.
* @param userId The userId of the logged in user. Can be null or undefined
* @throws { Meteor.Error } If there is no logged in user, or the user is not an Admin or Admin.
*/
public assertValidRoleForMethod(userId: string) {
this.assertRole(userId, [ROLE.ADMIN]);
}
/**
* Returns an array of strings, each one representing an integrity problem with this collection.
* Returns an empty array if no problems were found.
* Checks the profile common fields and the role..
* @returns {Array} A (possibly empty) array of strings indicating integrity issues.
*/
public checkIntegrity() {
let problems = [];
this.find().forEach((doc) => {
problems = problems.concat(this.checkIntegrityCommonFields(doc));
if (doc.role !== ROLE.ADMIN) {
problems.push(`AdminProfile instance does not have ROLE.ADMIN: ${doc}`);
}
});
return problems;
}
/**
* Returns an object representing the AdminProfile docID in a format acceptable to define().
* @param docID The docID of a AdminProfile
* @returns { Object } An object representing the definition of docID.
*/
public dumpOne(docID: string): ProfileDefine {
const doc = this.findDoc(docID);
const username = doc.username;
const firstName = doc.firstName;
const lastName = doc.lastName;
const picture = doc.picture;
const website = doc.website;
const userID = Users.getID(username);
const favInterests = FavoriteInterests.findNonRetired({ userID });
const interests = _.map(favInterests, (fav) => Interests.findSlugByID(fav.interestID));
const favCareerGoals = FavoriteCareerGoals.findNonRetired({ userID });
const careerGoals = _.map(favCareerGoals, (fav) => CareerGoals.findSlugByID(fav.careerGoalID));
const retired = doc.retired;
return { username, firstName, lastName, picture, website, interests, careerGoals, retired };
}
}
/**
* Provides the singleton instance of this class to all other entities.
* @type {api/user.AdminProfileCollection}
* @memberOf api/user
*/
export const AdminProfiles = new AdminProfileCollection();
Source