Source

api/interest/InterestKeywordCollection.ts

  1. import SimpleSchema from 'simpl-schema';
  2. import _ from 'lodash';
  3. import { InterestKeywordDefine, InterestKeywordUpdate } from '../../typings/radgrad';
  4. import BaseCollection from '../base/BaseCollection';
  5. import { ROLE } from '../role/Role';
  6. import { Interests } from './InterestCollection';
  7. /**
  8. * Mapping between interests and keywords.
  9. */
  10. class InterestKeywordCollection extends BaseCollection {
  11. /** Creates the InterestKeywordCollection. */
  12. constructor() {
  13. super(
  14. 'InterestKeyword',
  15. new SimpleSchema({
  16. interestID: SimpleSchema.RegEx.Id,
  17. keyword: String,
  18. retired: { type: Boolean, optional: true },
  19. }),
  20. );
  21. }
  22. /**
  23. * Defines a new interest keyword mapping.
  24. * @param {string} interest the interest slug or id.
  25. * @param {string} keyword the keyword.
  26. * @param {boolean | undefined} retired optional.
  27. * @return {string}
  28. */
  29. define({ interest, keyword, retired = false }: InterestKeywordDefine): string {
  30. const interestID = Interests.getID(interest);
  31. const doc = this.findOne({ interestID, keyword });
  32. if (doc) {
  33. return doc._id;
  34. }
  35. return this.collection.insert({ interestID, keyword, retired });
  36. }
  37. /**
  38. * Updates the given interest keyword pair.
  39. * @param docID the id of the pair.
  40. * @param {string | undefined} keyword the new keyword, optional.
  41. * @param {boolean | undefined} retired the retired status, optional.
  42. */
  43. update(docID, { keyword, retired }: InterestKeywordUpdate) {
  44. this.assertDefined(docID);
  45. const updateData: InterestKeywordUpdate = {};
  46. if (keyword) {
  47. updateData.keyword = keyword;
  48. }
  49. if (_.isBoolean(retired)) {
  50. updateData.retired = retired;
  51. }
  52. this.collection.update(docID, { $set: updateData });
  53. }
  54. /**
  55. * Removes the pair.
  56. * @param {string} docID the id of the pair.
  57. * @return {boolean}
  58. */
  59. removeIt(docID): boolean {
  60. this.assertDefined(docID);
  61. return super.removeIt(docID);
  62. }
  63. /**
  64. * Removes all the pairs for the given interest.
  65. * @param {string} interest the interest slug or id.
  66. */
  67. removeInterest(interest: string) {
  68. const interestID = Interests.getID(interest);
  69. this.collection.remove({ interestID });
  70. }
  71. /**
  72. * Removes all the pairs for the given keyword.
  73. * @param {string} keyword the keyword.
  74. */
  75. removeKeyword(keyword: string) {
  76. this.collection.remove({ keyword });
  77. }
  78. /**
  79. * Returns the keywords associated with the give interest.
  80. * @param interest the interest slug or id.
  81. * @return {string[]}
  82. */
  83. getKeywords(interest: string) {
  84. const interestID = Interests.getID(interest);
  85. return this.collection.find({ interestID }).fetch().map((ik) => ik.keyword);
  86. }
  87. /**
  88. * Returns the unique keywords in this collection.
  89. * @return {string[]}
  90. */
  91. getUniqueKeywords() {
  92. const keywords = this.collection.find({}).fetch().map(ik => ik.keyword);
  93. return _.uniq(keywords);
  94. }
  95. /**
  96. * Returns the interest slugs associated with the given keyword.
  97. * @param {string} keyword the keyword.
  98. * @return {string[]} the interest slugs.
  99. */
  100. getInterestSlugs(keyword: string) {
  101. const docs = this.collection.find({ keyword }).fetch();
  102. return docs.map(doc => Interests.findSlugByID(doc.interestID));
  103. }
  104. /**
  105. * Implementation of assertValidRoleForMethod. Asserts that userId is logged in as an Admin, Advisor or Student.
  106. * This is used in the define, update, and removeIt Meteor methods associated with each class.
  107. * @param userId The userId of the logged in user. Can be null or undefined
  108. * @throws { Meteor.Error } If there is no logged in user, or the user is not an Admin or Advisor.
  109. */
  110. assertValidRoleForMethod(userId) {
  111. this.assertRole(userId, [ROLE.ADMIN, ROLE.ADVISOR, ROLE.FACULTY]);
  112. }
  113. /**
  114. * Checks the interestIDs.
  115. * @return {any[]}
  116. */
  117. checkIntegrity() {
  118. const problems = [];
  119. this.find().forEach((doc) => {
  120. if (!Interests.isDefined(doc.interestID)) {
  121. problems.push(`Bad InterestID ${doc.interestID}`);
  122. }
  123. });
  124. return problems;
  125. }
  126. /**
  127. * Returns an object for the InterestKeyword docID in a format acceptable to define().
  128. * @param docID the id of the pair.
  129. * @return {InterestKeywordDefine}
  130. */
  131. dumpOne(docID): InterestKeywordDefine {
  132. const doc = this.findDoc(docID);
  133. const interest = Interests.findSlugByID(doc.interestID);
  134. const keyword = doc.keyword;
  135. const retired = doc.retired;
  136. return { interest, keyword, retired };
  137. }
  138. }
  139. export const InterestKeywords = new InterestKeywordCollection();