PersonalContainer.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import { Container } from 'unstated';
  2. import loggerFactory from '~/utils/logger';
  3. import { apiPost } from '../util/apiv1-client';
  4. import { apiv3Get, apiv3Put } from '../util/apiv3-client';
  5. // eslint-disable-next-line no-unused-vars
  6. const logger = loggerFactory('growi:services:PersonalContainer');
  7. const DEFAULT_IMAGE = '/images/icons/user.svg';
  8. /**
  9. * Service container for personal settings page (PersonalSettings.jsx)
  10. * @extends {Container} unstated Container
  11. */
  12. export default class PersonalContainer extends Container {
  13. constructor(appContainer) {
  14. super();
  15. this.appContainer = appContainer;
  16. this.state = {
  17. retrieveError: null,
  18. name: '',
  19. email: '',
  20. registrationWhiteList: this.appContainer.getConfig().registrationWhiteList,
  21. isEmailPublished: false,
  22. lang: 'en_US',
  23. isGravatarEnabled: false,
  24. isUploadedPicture: false,
  25. uploadedPictureSrc: this.getUploadedPictureSrc(this.appContainer.currentUser),
  26. externalAccounts: [],
  27. apiToken: '',
  28. slackMemberId: '',
  29. };
  30. }
  31. /**
  32. * Workaround for the mangling in production build to break constructor.name
  33. */
  34. static getClassName() {
  35. return 'PersonalContainer';
  36. }
  37. /**
  38. * retrieve personal data
  39. */
  40. async retrievePersonalData() {
  41. try {
  42. const response = await apiv3Get('/personal-setting/');
  43. const { currentUser } = response.data;
  44. this.setState({
  45. name: currentUser.name,
  46. email: currentUser.email,
  47. isEmailPublished: currentUser.isEmailPublished,
  48. lang: currentUser.lang,
  49. isGravatarEnabled: currentUser.isGravatarEnabled,
  50. apiToken: currentUser.apiToken,
  51. slackMemberId: currentUser.slackMemberId,
  52. });
  53. }
  54. catch (err) {
  55. this.setState({ retrieveError: err });
  56. logger.error(err);
  57. throw new Error('Failed to fetch personal data');
  58. }
  59. }
  60. /**
  61. * define a function for uploaded picture
  62. */
  63. getUploadedPictureSrc(user) {
  64. if (user == null) {
  65. return DEFAULT_IMAGE;
  66. }
  67. if (user.image) {
  68. this.setState({ isUploadedPicture: true });
  69. return user.image;
  70. }
  71. if (user.imageAttachment != null) {
  72. this.setState({ isUploadedPicture: true });
  73. return user.imageAttachment.filePathProxied;
  74. }
  75. return DEFAULT_IMAGE;
  76. }
  77. /**
  78. * retrieve external accounts that linked me
  79. */
  80. async retrieveExternalAccounts() {
  81. try {
  82. const response = await apiv3Get('/personal-setting/external-accounts');
  83. const { externalAccounts } = response.data;
  84. this.setState({ externalAccounts });
  85. }
  86. catch (err) {
  87. this.setState({ retrieveError: err });
  88. logger.error(err);
  89. throw new Error('Failed to fetch external accounts');
  90. }
  91. }
  92. /**
  93. * Change name
  94. */
  95. changeName(inputValue) {
  96. this.setState({ name: inputValue });
  97. }
  98. /**
  99. * Change email
  100. */
  101. changeEmail(inputValue) {
  102. this.setState({ email: inputValue });
  103. }
  104. /**
  105. * Change Slack Member ID
  106. */
  107. changeSlackMemberId(inputValue) {
  108. this.setState({ slackMemberId: inputValue });
  109. }
  110. /**
  111. * Change isEmailPublished
  112. */
  113. changeIsEmailPublished(boolean) {
  114. this.setState({ isEmailPublished: boolean });
  115. }
  116. /**
  117. * Change lang
  118. */
  119. changeLang(lang) {
  120. this.setState({ lang });
  121. }
  122. /**
  123. * Change isGravatarEnabled
  124. */
  125. changeIsGravatarEnabled(boolean) {
  126. this.setState({ isGravatarEnabled: boolean });
  127. }
  128. /**
  129. * Update basic info
  130. * @memberOf PersonalContainer
  131. * @return {Array} basic info
  132. */
  133. async updateBasicInfo() {
  134. try {
  135. const response = await apiv3Put('/personal-setting/', {
  136. name: this.state.name,
  137. email: this.state.email,
  138. isEmailPublished: this.state.isEmailPublished,
  139. lang: this.state.lang,
  140. slackMemberId: this.state.slackMemberId,
  141. });
  142. const { updatedUser } = response.data;
  143. this.setState({
  144. name: updatedUser.name,
  145. email: updatedUser.email,
  146. isEmailPublished: updatedUser.isEmailPublished,
  147. lang: updatedUser.lang,
  148. slackMemberId: updatedUser.slackMemberId,
  149. });
  150. }
  151. catch (err) {
  152. this.setState({ retrieveError: err });
  153. logger.error(err);
  154. throw new Error('Failed to update personal data');
  155. }
  156. }
  157. /**
  158. * Update profile image
  159. * @memberOf PersonalContainer
  160. */
  161. async updateProfileImage() {
  162. try {
  163. const response = await apiv3Put('/personal-setting/image-type', {
  164. isGravatarEnabled: this.state.isGravatarEnabled,
  165. });
  166. const { userData } = response.data;
  167. this.setState({
  168. isGravatarEnabled: userData.isGravatarEnabled,
  169. });
  170. }
  171. catch (err) {
  172. this.setState({ retrieveError: err });
  173. logger.error(err);
  174. throw new Error('Failed to update profile image');
  175. }
  176. }
  177. /**
  178. * Upload image
  179. */
  180. async uploadAttachment(file) {
  181. try {
  182. const formData = new FormData();
  183. formData.append('file', file);
  184. formData.append('_csrf', this.appContainer.csrfToken);
  185. const response = await apiPost('/attachments.uploadProfileImage', formData);
  186. this.setState({ isUploadedPicture: true, uploadedPictureSrc: response.attachment.filePathProxied });
  187. }
  188. catch (err) {
  189. this.setState({ retrieveError: err });
  190. logger.error(err);
  191. throw new Error('Failed to upload profile image');
  192. }
  193. }
  194. /**
  195. * Delete image
  196. */
  197. async deleteProfileImage() {
  198. try {
  199. await apiPost('/attachments.removeProfileImage', { _csrf: this.appContainer.csrfToken });
  200. this.setState({ isUploadedPicture: false, uploadedPictureSrc: DEFAULT_IMAGE });
  201. }
  202. catch (err) {
  203. this.setState({ retrieveError: err });
  204. logger.error(err);
  205. throw new Error('Failed to delete profile image');
  206. }
  207. }
  208. /**
  209. * Associate LDAP account
  210. */
  211. async associateLdapAccount(account) {
  212. try {
  213. await apiv3Put('/personal-setting/associate-ldap', account);
  214. }
  215. catch (err) {
  216. this.setState({ retrieveError: err });
  217. logger.error(err);
  218. throw new Error('Failed to associate ldap account');
  219. }
  220. }
  221. /**
  222. * Disassociate LDAP account
  223. */
  224. async disassociateLdapAccount(account) {
  225. try {
  226. await apiv3Put('/personal-setting/disassociate-ldap', account);
  227. }
  228. catch (err) {
  229. this.setState({ retrieveError: err });
  230. logger.error(err);
  231. throw new Error('Failed to disassociate ldap account');
  232. }
  233. }
  234. }