user-affiliations.pug 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. mixin aboutInstitutionLink()
  2. a(href="/learn/how-to/Institutional_Login") #{translate("find_out_more_about_institution_login")}.
  3. mixin btnMakePrimaryDisabled(tooltip)
  4. div(
  5. tooltip=tooltip
  6. tooltip-enable="!ui.isMakingRequest"
  7. ng-if="!userEmail.default && (!userEmail.confirmedAt || ui.isMakingRequest) && !institutionAlreadyLinked(userEmail)"
  8. )
  9. button.btn.btn-sm.btn-success.affiliations-table-inline-action(
  10. disabled
  11. type="button"
  12. ) #{translate("make_primary")}
  13. form.row(
  14. ng-controller="UserAffiliationsController"
  15. name="affiliationsForm"
  16. )
  17. .col-md-12
  18. h3 #{translate("emails_and_affiliations_title")}
  19. p.small #{translate("emails_and_affiliations_explanation")}
  20. table.table.affiliations-table
  21. thead
  22. tr
  23. th.affiliations-table-email #{translate("email")}
  24. th.affiliations-table-institution #{translate("institution_and_role")}
  25. th.affiliations-table-inline-actions
  26. tbody
  27. tr(
  28. ng-repeat-start="userEmail in userEmails"
  29. )
  30. td
  31. | {{ userEmail.email + (userEmail.default ? ' (primary)' : '') }}
  32. div(ng-if="!userEmail.confirmedAt").small
  33. strong #{translate('unconfirmed')}.
  34. span(ng-if="!userEmail.ssoAvailable")  #{translate('please_check_your_inbox')}.
  35. br
  36. a(
  37. href,
  38. ng-click="resendConfirmationEmail(userEmail)",
  39. ng-if="!userEmail.ssoAvailable"
  40. ) #{translate('resend_confirmation_email')}
  41. div(ng-if="userEmail.confirmedAt && userEmail.affiliation.institution && userEmail.affiliation.institution.confirmed && userEmail.affiliation.licence && userEmail.affiliation.licence != 'free'").small
  42. span.label.label-primary #{translate("professional")}
  43. td
  44. div(ng-if="userEmail.affiliation.institution")
  45. div {{ userEmail.affiliation.institution.name }}
  46. span.small
  47. a(
  48. href
  49. ng-if="!isChangingAffiliation(userEmail.email) && !userEmail.affiliation.role && !userEmail.affiliation.department"
  50. ng-click="changeAffiliation(userEmail);"
  51. ) #{translate("add_role_and_department")}
  52. div.small(
  53. ng-if="!isChangingAffiliation(userEmail.email) && (userEmail.affiliation.role || userEmail.affiliation.department)"
  54. )
  55. span(ng-if="userEmail.affiliation.role") {{ userEmail.affiliation.role }}
  56. span(ng-if="userEmail.affiliation.role && userEmail.affiliation.department") ,
  57. span(ng-if="userEmail.affiliation.department") {{ userEmail.affiliation.department }}
  58. br
  59. a(
  60. href
  61. ng-click="changeAffiliation(userEmail);"
  62. ) #{translate("change")}
  63. .affiliation-change-container(
  64. ng-if="isChangingAffiliation(userEmail.email)"
  65. )
  66. affiliation-form(
  67. affiliation-data="affiliationToChange"
  68. show-university-and-country="false"
  69. show-role-and-department="true"
  70. )
  71. .affiliation-change-actions.small
  72. button.btn.btn-sm.btn-success(
  73. ng-click="saveAffiliationChange(userEmail);"
  74. ng-disabled="!(affiliationToChange.role && affiliationToChange.department)"
  75. type="button"
  76. ) #{translate("save_or_cancel-save")}
  77. |  #{translate("save_or_cancel-or" )} 
  78. a(
  79. href
  80. ng-click="cancelAffiliationChange();"
  81. ) #{translate("save_or_cancel-cancel")}
  82. td.affiliations-table-inline-actions
  83. // Disabled buttons don't work with tooltips, due to pointer-events: none,
  84. // so create a wrapper for the tooltip
  85. .affiliations-table-inline-action-disabled-wrapper(ng-if="userEmail.ssoAvailable")
  86. +btnMakePrimaryDisabled("Please confirm your email by linking to your institutional account before making it the primary email.")
  87. .affiliations-table-inline-action-disabled-wrapper(ng-if="!userEmail.ssoAvailable")
  88. +btnMakePrimaryDisabled(translate("please_confirm_your_email_before_making_it_default"))
  89. button.btn.btn-sm.btn-success.affiliations-table-inline-action(
  90. tooltip=translate("make_email_primary_description")
  91. ng-if="!userEmail.default && (userEmail.confirmedAt && !ui.isMakingRequest)"
  92. ng-click="setDefaultUserEmail(userEmail)"
  93. type="button"
  94. ) #{translate("make_primary")}
  95. |  
  96. button.btn.btn-sm.btn-danger.affiliations-table-inline-action(
  97. ng-if="!userEmail.default"
  98. ng-click="removeUserEmail(userEmail)"
  99. ng-disabled="ui.isMakingRequest"
  100. tooltip=translate("remove")
  101. type="button"
  102. )
  103. i.fa.fa-fw.fa-trash(aria-hidden="true")
  104. span.sr-only #{translate("remove")}
  105. tr.affiliations-table-saml-row(ng-repeat-end ng-if="userEmail.affiliation && userEmail.affiliation && userEmail.ssoAvailable")
  106. td
  107. td(ng-attr-colspan="{{userEmail.samlProviderId ? '2' : '1'}}" ng-class="institutionAlreadyLinked(userEmail) ? '' : 'with-border'")
  108. p.small(ng-if="userEmail.samlProviderId")
  109. | !{translate("acct_linked_to_institution_acct", {institutionName: '{{userEmail.affiliation.institution.name}}'})}
  110. div(ng-if="!userEmail.samlProviderId && !institutionAlreadyLinked(userEmail)")
  111. //- this email is not linked to institution login but
  112. //- cannot have multiple emails at same institution linked for "institution login"
  113. //- so check if institution is already linked
  114. p.small
  115. | !{translate("can_link_your_institution_acct", {institutionName: '{{userEmail.affiliation.institution.name}}'})}
  116. p.small
  117. | !{translate("doing_this_allow_log_in_through_institution")} 
  118. +aboutInstitutionLink()
  119. td.with-border.affiliations-table-inline-actions(ng-if="!userEmail.samlProviderId && !institutionAlreadyLinked(userEmail)")
  120. button.btn-sm.btn.btn-info(
  121. ng-click="linkInstitutionAcct(userEmail.email, userEmail.affiliation.institution.id)"
  122. ng-disabled="ui.isMakingRequest"
  123. type="button"
  124. )
  125. | #{translate("link_accounts")}
  126. tr.affiliations-table-highlighted-row(
  127. ng-if="!ui.showAddEmailUI && !ui.isMakingRequest"
  128. )
  129. td(colspan="3")
  130. a(
  131. href
  132. ng-click="showAddEmailForm()"
  133. ) #{translate("add_another_email")}
  134. tr.affiliations-table-highlighted-row(
  135. ng-if="ui.showAddEmailUI && !ui.isLoadingEmails"
  136. )
  137. td
  138. .affiliations-form-group
  139. input-suggestions(
  140. ng-model="newAffiliation.email"
  141. ng-model-options="{ allowInvalid: true }"
  142. get-suggestion="getEmailSuggestion(userInput)"
  143. on-blur="handleEmailInputBlur()"
  144. input-id="affilitations-email"
  145. input-name="affilitationsEmail"
  146. input-placeholder="e.g. johndoe@mit.edu"
  147. input-type="email"
  148. input-required="true"
  149. )
  150. td(
  151. colspan="2"
  152. ng-if="newAffiliation.ssoAvailable"
  153. )
  154. p.affiliations-table-label {{ newAffiliation.university.name }}
  155. p !{translate("to_add_email_accounts_need_to_be_linked", {institutionName: "{{newAffiliation.university.name}}"})}
  156. p !{translate("doing_this_will_verify_affiliation_and_allow_log_in", {institutionName: "{{newAffiliation.university.name}}"})} 
  157. +aboutInstitutionLink()
  158. button.btn-sm.btn.btn-primary.btn-link-accounts(
  159. ng-click="linkInstitutionAcct(newAffiliation.email, newAffiliation.university.id)"
  160. ng-disabled="ui.isMakingRequest"
  161. type="button"
  162. )
  163. | #{translate("link_accounts_and_add_email")}
  164. td(
  165. ng-if="!newAffiliation.ssoAvailable"
  166. )
  167. p.affiliations-table-label(
  168. ng-if="newAffiliation.university && !ui.showManualUniversitySelectionUI"
  169. )
  170. | {{ newAffiliation.university.name }}
  171. span.small
  172. | (
  173. a(
  174. href
  175. ng-click="selectUniversityManually();"
  176. ) #{translate("change")}
  177. | )
  178. .affiliations-table-label(
  179. ng-if="!newAffiliation.university && !ui.isValidEmail && !ui.showManualUniversitySelectionUI"
  180. ) #{translate("start_by_adding_your_email")}
  181. .affiliations-table-label(
  182. ng-if="!newAffiliation.university && ui.isValidEmail && !ui.isBlacklistedEmail && !ui.showManualUniversitySelectionUI"
  183. )
  184. | #{translate("is_email_affiliated")}
  185. br
  186. a(
  187. href
  188. ng-click="selectUniversityManually();"
  189. ) #{translate("let_us_know")}
  190. affiliation-form(
  191. affiliation-data="newAffiliation"
  192. show-university-and-country="ui.showManualUniversitySelectionUI"
  193. show-role-and-department="ui.isValidEmail && newAffiliation.university"
  194. )
  195. td(
  196. ng-if="!newAffiliation.ssoAvailable"
  197. )
  198. button.btn.btn-sm.btn-primary(
  199. ng-disabled="affiliationsForm.$invalid || ui.isMakingRequest"
  200. ng-click="addNewEmail()"
  201. )
  202. | #{translate("add_new_email")}
  203. tr.affiliations-table-highlighted-row(
  204. ng-if="ui.isMakingRequest"
  205. )
  206. td.text-center(colspan="3", ng-if="ui.isLoadingEmails")
  207. i.fa.fa-fw.fa-spin.fa-refresh(aria-hidden="true")
  208. |  #{translate("loading")}...
  209. td.text-center(colspan="3", ng-if="ui.isResendingConfirmation")
  210. i.fa.fa-fw.fa-spin.fa-refresh(aria-hidden="true")
  211. |  #{translate("sending")}...
  212. td.text-center.text-capitalize(colspan="3", ng-if="ui.isProcessing")
  213. i.fa.fa-fw.fa-spin.fa-refresh(aria-hidden="true")
  214. |  #{translate("processing")}
  215. td.text-center(colspan="3", ng-if="!ui.isLoadingEmails && !ui.isResendingConfirmation && !ui.isProcessing")
  216. i.fa.fa-fw.fa-spin.fa-refresh(aria-hidden="true")
  217. |  #{translate("saving")}
  218. tr.affiliations-table-error-row(
  219. ng-if="ui.hasError"
  220. )
  221. td.text-center(colspan="3")
  222. div
  223. i.fa.fa-fw.fa-exclamation-triangle(aria-hidden="true")
  224. span(ng-if="!ui.errorMessage")  #{translate("error_performing_request")}
  225. span(ng-if="ui.errorMessage")  {{ui.errorMessage}}
  226. if institutionLinked
  227. tr.affiliations-table-info-row(ng-if="!hideInstitutionNotifications.info")
  228. td.text-center(aria-live="assertive" colspan="3")
  229. button.close(
  230. type="button"
  231. data-dismiss="modal"
  232. ng-click="closeInstitutionNotification('info')"
  233. aria-label=translate("close")
  234. )
  235. span(aria-hidden="true") ×
  236. .small !{translate("institution_acct_successfully_linked", {institutionName: institutionLinked.universityName})}
  237. if institutionLinked.hasEntitlement
  238. .small !{translate("this_grants_access_to_features", {featureType: translate("professional")})}
  239. if institutionEmailNonCanonical
  240. tr.affiliations-table-warning-row(ng-if="!hideInstitutionNotifications.warning")
  241. td.text-center(aria-live="assertive" colspan="3")
  242. button.close(
  243. type="button"
  244. data-dismiss="modal"
  245. ng-click="closeInstitutionNotification('warning')"
  246. aria-label=translate("close")
  247. )
  248. span(aria-hidden="true") ×
  249. .small
  250. i.fa.fa-exclamation-triangle(aria-hidden="true")
  251. |  
  252. | !{translate("in_order_to_match_institutional_metadata", {email: institutionEmailNonCanonical})}
  253. if institutionLinkedToAnother
  254. tr.affiliations-table-error-row(ng-if="!hideInstitutionNotifications.error")
  255. td.text-center(aria-live="assertive" colspan="3")
  256. button.close(
  257. type="button"
  258. data-dismiss="modal"
  259. ng-click="closeInstitutionNotification('error')"
  260. aria-label=translate("close")
  261. )
  262. span(aria-hidden="true") ×
  263. .small
  264. i.fa.fa-exclamation-triangle(aria-hidden="true")
  265. |  
  266. | !{translate("institution_account_tried_to_add_already_registered")}
  267. hr
  268. script(type="text/ng-template", id="affiliationFormTpl")
  269. .affiliations-form-group(
  270. ng-if="$ctrl.showUniversityAndCountry"
  271. )
  272. ui-select(
  273. ng-model="$ctrl.affiliationData.country"
  274. )
  275. ui-select-match(
  276. placeholder="Country"
  277. ) {{ $select.selected.name }}
  278. ui-select-choices(
  279. repeat="country in $ctrl.countries | filter: $select.search"
  280. )
  281. span(
  282. ng-bind="country.name"
  283. )
  284. .affiliations-form-group(
  285. ng-if="$ctrl.showUniversityAndCountry"
  286. )
  287. ui-select(
  288. ng-model="$ctrl.affiliationData.university"
  289. ng-disabled="!$ctrl.affiliationData.country"
  290. tagging="$ctrl.addUniversityToSelection"
  291. tagging-label="false"
  292. )
  293. ui-select-match(
  294. placeholder="Institution"
  295. ) {{ $select.selected.name }}
  296. ui-select-choices(
  297. repeat="university in $ctrl.universities | filter: $select.search"
  298. refresh="$ctrl.handleFreeformInputChange($select, 'name');"
  299. refresh-delay="10"
  300. )
  301. span(
  302. ng-bind="university.name"
  303. )
  304. .affiliations-form-group(
  305. ng-if="$ctrl.showRoleAndDepartment"
  306. )
  307. ui-select(
  308. ng-model="$ctrl.affiliationData.role"
  309. tagging
  310. tagging-label="false"
  311. )
  312. ui-select-match(
  313. placeholder="Role"
  314. ) {{ $select.selected }}
  315. ui-select-choices(
  316. repeat="role in $ctrl.roles | filter: $select.search"
  317. refresh="$ctrl.handleFreeformInputChange($select);"
  318. refresh-delay="10"
  319. )
  320. span(
  321. ng-bind="role"
  322. )
  323. .affiliations-form-group(
  324. ng-if="$ctrl.showRoleAndDepartment"
  325. )
  326. ui-select(
  327. ng-model="$ctrl.affiliationData.department"
  328. tagging
  329. tagging-label="false"
  330. )
  331. ui-select-match(
  332. placeholder="Department"
  333. ) {{ $select.selected }}
  334. ui-select-choices(
  335. repeat="department in $ctrl.departments | filter: $select.search"
  336. refresh="$ctrl.handleFreeformInputChange($select);"
  337. refresh-delay="10"
  338. )
  339. span(
  340. ng-bind="department"
  341. )