AddFolderAction.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| IBM Cognos Products: Content Explorer
  5. *| (C) Copyright IBM Corp. 2015, 2018
  6. *|
  7. *| US Government Users Restricted Rights - Use, duplication or disclosure
  8. *| restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *+------------------------------------------------------------------------+
  10. */
  11. import { GlassContextHelper } from '@businessanalytics/content-nav';
  12. export class AddFolderAction {
  13. constructor() {
  14. this.duplicateFileCount = 0;
  15. }
  16. addFolder = (glassContext, url, fileName, fileList, l10n) => {
  17. if (!fileName || fileName === '') {
  18. fileName = l10n.get('newFolderDefaultName');
  19. }
  20. const requestOptions = {
  21. 'headers': {
  22. 'Accept': 'application/json',
  23. 'Content-Type': 'application/json'
  24. },
  25. 'type': 'POST',
  26. 'url': url,
  27. 'data': JSON.stringify({ defaultName: fileName, type: 'folder' })
  28. };
  29. if(this.includesUnsafeApostrophe(fileName)){
  30. GlassContextHelper.displayToast(glassContext, 'cannot create a folder with \' and " characters', { type: 'error' });
  31. return Promise.reject('cannot include both \' and "');
  32. }
  33. return glassContext.getCoreSvc('.Ajax').ajax(requestOptions)
  34. .then(() => {
  35. this.duplicateFileCount = 0;
  36. return Promise.resolve(fileName);
  37. })
  38. .catch((err) => {
  39. return this.handleAddItemError(glassContext, err, fileName, fileList, l10n)
  40. .then((data) => {
  41. return this.addFolder(glassContext, url, data.fileName, fileList);
  42. })
  43. .catch((err) => {
  44. GlassContextHelper.showAjaxServiceError(glassContext, err);
  45. return Promise.reject(err);
  46. });
  47. });
  48. }
  49. includesUnsafeApostrophe = (fileName) => {
  50. if ((fileName.indexOf('\'') > -1) && (fileName.indexOf('"') > -1)){
  51. return true;
  52. } else {
  53. return false;
  54. }
  55. };
  56. handleAddItemError = (glassContext, err, fileName, fileList, l10n) => {
  57. if (err.code === 400) {
  58. if (this.isNameConflict(err)){
  59. const newFileName = this.getNewNameString(fileName, fileList);
  60. if (this.duplicateFileCount < 20){
  61. return Promise.resolve({ fileName: newFileName });
  62. } else if (this.duplicateFileCount >= 20) {
  63. const errorMsg = l10n.get('itemsOverLimit', {
  64. itemName: fileName
  65. });
  66. GlassContextHelper.displayToast(glassContext, errorMsg, { type: 'error' });
  67. let responseJSON = err.jqXHR && err.jqXHR.responseJSON || {};
  68. responseJSON.messages.splice(1, 1);
  69. responseJSON.messages[0] = errorMsg;
  70. return Promise.reject(errorMsg);
  71. }
  72. } else if (this.isStringTruncationError(err)) {
  73. const errorMsg = l10n.get('errorMessageLengthFolderName');
  74. GlassContextHelper.displayToast(glassContext, errorMsg, { type: 'error' });
  75. let responseJSON = err.jqXHR && err.jqXHR.responseJSON || {};
  76. responseJSON.messages.splice(1, 1);
  77. responseJSON.messages[0] = errorMsg;
  78. return Promise.reject(errorMsg);
  79. }
  80. }
  81. return Promise.reject(err);
  82. }
  83. isStringTruncationError = (error) => {
  84. const errorCode = (error && error.jqXHR && error.jqXHR.responseJSON && error.jqXHR.responseJSON.errorCode) || '';
  85. if (error && error.code === 400) {
  86. return (errorCode.indexOf('cmStringTruncationException') !== -1);
  87. }
  88. }
  89. // TODO: move this general function to a content-nav ContentManagement file
  90. isNameConflict = (error) => {
  91. const errorCode = (error && error.jqXHR && error.jqXHR.responseJSON && error.jqXHR.responseJSON.errorCode) || '';
  92. if (error && error.code === 400) {
  93. if (errorCode.indexOf('cmUpdateFailed1') !== -1) {
  94. //check if we have a CM-REQ-4036 error (duplicate error).
  95. var jqXHRMessages = error.jqXHR.responseJSON.messages || [];
  96. return jqXHRMessages.some((message) => {
  97. return message.indexOf('CM-REQ-4036') !== -1;
  98. });
  99. } else {
  100. return ['cmDuplicateName','cmNameConflict', 'cmDuplicateObject'].indexOf(errorCode) !== -1;
  101. }
  102. }
  103. return false;
  104. }
  105. // TODO: possibly move this to another helper file
  106. getNewNameString = (fileName, fileList) => {
  107. let duplicateNameList = [];
  108. fileList.map((item) => {
  109. const name = item.defaultName.toLowerCase();
  110. if (name.indexOf(fileName.toLowerCase()) === 0) {
  111. duplicateNameList.push(name);
  112. }
  113. });
  114. let newNameString;
  115. for (var i = 1; i <= duplicateNameList.length; i++) {
  116. newNameString = fileName + ' (' + i + ')';
  117. if(!duplicateNameList.includes(newNameString.toLowerCase())){
  118. break;
  119. }
  120. }
  121. this.duplicateFileCount = i;
  122. return newNameString ? newNameString : fileName;
  123. }
  124. }