UNPKG

metadata-based-explorer1

Version:
1,464 lines (1,216 loc) 53.1 kB
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * * @file Helper for activity feed API's * @author Box */ import uniqueId from 'lodash/uniqueId'; import noop from 'lodash/noop'; import omit from 'lodash/omit'; import { getBadItemError, getBadUserError, isUserCorrectableError } from '../utils/error'; import commonMessages from '../elements/common/messages'; import messages from './messages'; import { sortFeedItems } from '../utils/sorter'; import Base from './Base'; import CommentsAPI from './Comments'; import VersionsAPI from './Versions'; import TasksAPI from './tasks/Tasks'; import TasksNewAPI from './tasks/TasksNew'; import TaskCollaboratorsAPI from './tasks/TaskCollaborators'; import TaskLinksAPI from './tasks/TaskLinks'; import TaskAssignmentsAPI from './tasks/TaskAssignments'; import AppActivityAPI from './AppActivity'; import { ERROR_CODE_CREATE_TASK, ERROR_CODE_CREATE_TASK_ASSIGNMENT, ERROR_CODE_UPDATE_TASK, HTTP_STATUS_CODE_CONFLICT, IS_ERROR_DISPLAYED, TASK_INCOMPLETE, TASK_NEW_APPROVED, TASK_NEW_COMPLETED, TASK_NEW_REJECTED, TASK_NEW_NOT_STARTED, TYPED_ID_FEED_PREFIX } from '../constants'; var TASK_NEW_INITIAL_STATUS = TASK_NEW_NOT_STARTED; var TASK = 'task'; var TASK_ASSIGNMENT = 'task_assignment'; var TASK_ASSIGNMENT_COLLECTION = 'task_assignment_collection'; var Feed = /*#__PURE__*/ function (_Base) { _inherits(Feed, _Base); /** * @property {VersionsAPI} */ /** * @property {CommentsAPI} */ /** * @property {TasksAPI} */ /** * @property {TaskAssignmentsAPI} */ /** * @property {AppActivityAPI} */ /** * @property {TasksNewAPI} */ /** * @property {TaskCollaboratorsAPI} */ /** * @property {TaskLinksAPI} */ /** * @property {BoxItem} */ /** * @property {boolean} */ function Feed(options) { var _this; _classCallCheck(this, Feed); _this = _possibleConstructorReturn(this, _getPrototypeOf(Feed).call(this, options)); _defineProperty(_assertThisInitialized(_this), "updateTaskAssignment", function (file, taskId, taskAssignmentId, taskStatus, _successCallback, errorCallback) { if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.updateFeedItem({ isPending: true }, taskId); var assignmentAPI = new TaskAssignmentsAPI(_this.options); _this.taskAssignmentsAPI.push(assignmentAPI); assignmentAPI.updateTaskAssignment({ file: file, taskAssignmentId: taskAssignmentId, taskStatus: taskStatus, successCallback: function successCallback(taskAssignment) { _this.updateTaskAssignmentSuccessCallback(taskId, taskAssignment, _successCallback); }, errorCallback: function errorCallback(e, code) { _this.feedErrorCallback(true, e, code); } }); }); _defineProperty(_assertThisInitialized(_this), "updateTaskAssignmentSuccessCallback", function (taskId, updatedAssignment, successCallback) { var cachedItems = _this.getCachedItems(_this.file.id); if (cachedItems) { // $FlowFixMe var _task = cachedItems.items.find(function (item) { return item.type === TASK && item.id === taskId; }); if (_task) { var _task$task_assignment = _task.task_assignment_collection, entries = _task$task_assignment.entries, total_count = _task$task_assignment.total_count; var assignments = entries.map(function (item) { if (item.id === updatedAssignment.id) { return _objectSpread({}, item, {}, updatedAssignment); } return item; }); _this.updateFeedItem({ task_assignment_collection: { entries: assignments, total_count: total_count }, isPending: false }, taskId); successCallback(updatedAssignment); } } }); _defineProperty(_assertThisInitialized(_this), "updateTaskCollaborator", function (file, taskId, taskCollaboratorId, taskCollaboratorStatus, _successCallback2, errorCallback) { if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.updateFeedItem({ isPending: true }, taskId); var collaboratorsApi = new TaskCollaboratorsAPI(_this.options); _this.taskCollaboratorsAPI.push(collaboratorsApi); var taskCollaboratorPayload = { id: taskCollaboratorId, status: taskCollaboratorStatus }; var handleError = function handleError(e, code) { var errorMessage; switch (taskCollaboratorStatus) { case TASK_NEW_APPROVED: errorMessage = messages.taskApproveErrorMessage; break; case TASK_NEW_COMPLETED: errorMessage = messages.taskCompleteErrorMessage; break; case TASK_NEW_REJECTED: errorMessage = messages.taskRejectErrorMessage; break; default: errorMessage = messages.taskCompleteErrorMessage; } _this.updateFeedItem(_this.createFeedError(errorMessage, messages.taskActionErrorTitle), taskId); _this.feedErrorCallback(true, e, code); }; collaboratorsApi.updateTaskCollaborator({ file: file, taskCollaborator: taskCollaboratorPayload, successCallback: function successCallback(taskCollab) { _this.updateTaskCollaboratorSuccessCallback(taskId, file, taskCollab, _successCallback2, handleError); }, errorCallback: handleError }); }); _defineProperty(_assertThisInitialized(_this), "updateTaskCollaboratorSuccessCallback", function (taskId, file, updatedCollaborator, _successCallback3, errorCallback) { _this.tasksNewAPI = new TasksNewAPI(_this.options); _this.tasksNewAPI.getTask({ id: taskId, file: file, successCallback: function successCallback(task) { _this.updateFeedItem(_objectSpread({}, task, { isPending: false }), taskId); _successCallback3(updatedCollaborator); }, errorCallback: errorCallback }); }); _defineProperty(_assertThisInitialized(_this), "updateTask", function (file, taskId, message) { var _successCallback4 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop; var errorCallback = arguments.length > 4 ? arguments[4] : undefined; var dueAt = arguments.length > 5 ? arguments[5] : undefined; if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.updateFeedItem({ isPending: true }, taskId); _this.tasksAPI = new TasksAPI(_this.options); _this.tasksAPI.updateTask({ file: file, taskId: taskId, message: message, dueAt: dueAt, successCallback: function successCallback(task) { _this.updateTaskSuccessCallback(task, _successCallback4); }, errorCallback: function errorCallback(e, code) { _this.feedErrorCallback(true, e, code); } }); }); _defineProperty(_assertThisInitialized(_this), "updateTaskNew", function (file, task) { var _successCallback5 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop; var errorCallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop; if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.tasksNewAPI = new TasksNewAPI(_this.options); _this.updateFeedItem({ isPending: true }, task.id); Promise.all(task.addedAssignees.map(function (assignee) { return _this.createTaskCollaborator(file, task, assignee); })).then(function () { return Promise.all(task.removedAssignees.map(function (assignee) { return _this.deleteTaskCollaborator(file, task, assignee); })); }).then(function () { _this.tasksNewAPI.updateTask({ file: file, task: task, successCallback: function successCallback(taskData) { _this.updateFeedItem(_objectSpread({}, taskData, { isPending: false }), task.id); if (!_this.isDestroyed()) { _successCallback5(); } }, errorCallback: function errorCallback(e) { _this.updateFeedItem({ isPending: false }, task.id); _this.feedErrorCallback(false, e, ERROR_CODE_UPDATE_TASK); } }); }).catch(function (e) { _this.updateFeedItem({ isPending: false }, task.id); _this.feedErrorCallback(false, e, ERROR_CODE_UPDATE_TASK); }); }); _defineProperty(_assertThisInitialized(_this), "updateTaskSuccessCallback", function (task, successCallback) { var updates = omit(task, TASK_ASSIGNMENT_COLLECTION); _this.updateFeedItem(_objectSpread({}, updates, { isPending: false }), task.id); if (!_this.isDestroyed()) { successCallback(task); } }); _defineProperty(_assertThisInitialized(_this), "deleteComment", function (file, commentId, permissions, successCallback, errorCallback) { _this.commentsAPI = new CommentsAPI(_this.options); if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.updateFeedItem({ isPending: true }, commentId); _this.commentsAPI.deleteComment({ file: file, commentId: commentId, permissions: permissions, successCallback: _this.deleteFeedItem.bind(_assertThisInitialized(_this), commentId, successCallback), errorCallback: function errorCallback(e, code) { _this.deleteCommentErrorCallback(e, code, commentId); } }); }); _defineProperty(_assertThisInitialized(_this), "deleteCommentErrorCallback", function (e, code, commentId) { _this.updateFeedItem(_this.createFeedError(messages.commentDeleteErrorMessage), commentId); _this.feedErrorCallback(true, e, code); }); _defineProperty(_assertThisInitialized(_this), "createTask", function (file, currentUser, message, assignees, dueAt, _successCallback6, errorCallback) { if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; var uuid = uniqueId('task_'); var dueAtString; if (dueAt) { var dueAtDate = new Date(dueAt); dueAtString = dueAtDate.toISOString(); } var pendingAssignees = assignees.map(function (assignee) { return { assigned_to: { id: assignee.id, name: assignee.name }, status: TASK_INCOMPLETE }; }); var task = { due_at: dueAtString, id: uuid, is_completed: false, message: message, task_assignment_collection: { entries: pendingAssignees, total_count: pendingAssignees.length }, type: TASK }; _this.addPendingItem(_this.file.id, currentUser, task); _this.tasksAPI = new TasksAPI(_this.options); _this.tasksAPI.createTask({ file: file, message: message, dueAt: dueAtString, successCallback: function successCallback(taskData) { _this.createTaskSuccessCallback(file, uuid, taskData, assignees, _successCallback6, errorCallback); }, errorCallback: function errorCallback(e, code) { _this.updateFeedItem(_this.createFeedError(messages.taskCreateErrorMessage), uuid); _this.feedErrorCallback(false, e, code); } }); }); _defineProperty(_assertThisInitialized(_this), "createTaskNew", function (file, currentUser, message, assignees, taskType, dueAt, completionRule, _successCallback7, errorCallback) { if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; var uuid = uniqueId('task_'); var dueAtString; if (dueAt) { var dueAtDate = new Date(dueAt); dueAtString = dueAtDate.toISOString(); } // TODO: make pending task generator a function var pendingTask = { created_by: { type: 'task_collaborator', target: currentUser, id: uniqueId(), role: 'CREATOR', status: TASK_NEW_INITIAL_STATUS }, completion_rule: completionRule, created_at: new Date().toISOString(), due_at: dueAtString, id: uuid, description: message, type: TASK, assigned_to: { entries: assignees.map(function (assignee) { return { id: uniqueId(), target: _objectSpread({}, assignee, { avatar_url: '', type: 'user' }), status: TASK_NEW_INITIAL_STATUS, permissions: { can_delete: false, can_update: false }, role: 'ASSIGNEE', type: 'task_collaborator' }; }), limit: 10, next_marker: null }, permissions: { can_update: false, can_delete: false, can_create_task_collaborator: false, can_create_task_link: false }, task_links: { entries: [{ id: uniqueId(), type: 'task_link', target: _objectSpread({ type: 'file' }, file), permissions: { can_delete: false, can_update: false } }], limit: 1, next_marker: null }, task_type: taskType, status: TASK_NEW_NOT_STARTED }; var taskPayload = { description: message, due_at: dueAtString, task_type: taskType, completion_rule: completionRule }; _this.tasksNewAPI = new TasksNewAPI(_this.options); _this.tasksNewAPI.createTask({ file: file, task: taskPayload, successCallback: function successCallback(taskData) { _this.addPendingItem(_this.file.id, currentUser, pendingTask); _this.createTaskNewSuccessCallback(file, uuid, taskData, assignees, _successCallback7, errorCallback); }, errorCallback: function errorCallback(e, code) { _this.feedErrorCallback(false, e, code); } }); }); _defineProperty(_assertThisInitialized(_this), "deleteTask", function (file, taskId) { var successCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop; var errorCallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop; if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.tasksAPI = new TasksAPI(_this.options); _this.updateFeedItem({ isPending: true }, taskId); _this.tasksAPI.deleteTask({ file: file, taskId: taskId, successCallback: _this.deleteFeedItem.bind(_assertThisInitialized(_this), taskId, successCallback), errorCallback: function errorCallback(e, code) { _this.feedErrorCallback(true, e, code); } }); }); _defineProperty(_assertThisInitialized(_this), "deleteTaskNew", function (file, task) { var successCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop; var errorCallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop; if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.tasksNewAPI = new TasksNewAPI(_this.options); _this.updateFeedItem({ isPending: true }, task.id); _this.tasksNewAPI.deleteTask({ file: file, task: task, successCallback: _this.deleteFeedItem.bind(_assertThisInitialized(_this), task.id, successCallback), errorCallback: function errorCallback(e, code) { _this.updateFeedItem(_this.createFeedError(messages.taskDeleteErrorMessage), task.id); _this.feedErrorCallback(true, e, code); } }); }); _defineProperty(_assertThisInitialized(_this), "deleteFeedItem", function (id) { var successCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop; var cachedItems = _this.getCachedItems(_this.file.id); if (cachedItems) { var _feedItems2 = cachedItems.items.filter(function (feedItem) { return feedItem.id !== id; }); _this.setCachedItems(_this.file.id, _feedItems2); if (!_this.isDestroyed()) { successCallback(id); } } }); _defineProperty(_assertThisInitialized(_this), "feedErrorCallback", function () { var hasError = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var e = arguments.length > 1 ? arguments[1] : undefined; var code = arguments.length > 2 ? arguments[2] : undefined; if (hasError) { _this.hasError = true; } if (!_this.isDestroyed() && _this.errorCallback) { _this.errorCallback(e, code, _defineProperty({ error: e }, IS_ERROR_DISPLAYED, hasError)); } console.error(e); // eslint-disable-line no-console }); _defineProperty(_assertThisInitialized(_this), "addPendingItem", function (id, currentUser, itemBase) { if (!currentUser) { throw getBadUserError(); } var date = new Date().toISOString(); var pendingFeedItem = _objectSpread({ created_at: date, created_by: currentUser, modified_at: date, isPending: true }, itemBase); var cachedItems = _this.getCachedItems(_this.file.id); var feedItems = cachedItems ? cachedItems.items : []; var feedItemsWithPendingItem = [].concat(_toConsumableArray(feedItems), [pendingFeedItem]); _this.setCachedItems(id, feedItemsWithPendingItem); return pendingFeedItem; }); _defineProperty(_assertThisInitialized(_this), "createCommentSuccessCallback", function (commentData, id, successCallback) { var _commentData$message = commentData.message, message = _commentData$message === void 0 ? '' : _commentData$message, _commentData$tagged_m = commentData.tagged_message, tagged_message = _commentData$tagged_m === void 0 ? '' : _commentData$tagged_m; // Comment component uses tagged_message only commentData.tagged_message = tagged_message || message; _this.updateFeedItem(_objectSpread({}, commentData, { isPending: false }), id); if (!_this.isDestroyed()) { successCallback(commentData); } }); _defineProperty(_assertThisInitialized(_this), "createCommentErrorCallback", function (e, code, id) { var errorMessage = e.status === HTTP_STATUS_CODE_CONFLICT ? messages.commentCreateConflictMessage : messages.commentCreateErrorMessage; _this.updateFeedItem(_this.createFeedError(errorMessage), id); _this.feedErrorCallback(false, e, code); }); _defineProperty(_assertThisInitialized(_this), "updateFeedItem", function (updates, id) { if (!_this.file.id) { throw getBadItemError(); } var cachedItems = _this.getCachedItems(_this.file.id); if (cachedItems) { var updatedFeedItems = cachedItems.items.map(function (item) { if (item.id === id) { return _objectSpread({}, item, {}, updates); } return item; }); _this.setCachedItems(_this.file.id, updatedFeedItems); return updatedFeedItems; } return null; }); _defineProperty(_assertThisInitialized(_this), "createComment", function (file, currentUser, text, hasMention, _successCallback8, errorCallback) { var uuid = uniqueId('comment_'); var commentData = { id: uuid, tagged_message: text, type: 'comment' }; if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.addPendingItem(_this.file.id, currentUser, commentData); var message = {}; if (hasMention) { message.taggedMessage = text; } else { message.message = text; } _this.commentsAPI = new CommentsAPI(_this.options); _this.commentsAPI.createComment(_objectSpread({ file: file }, message, { successCallback: function successCallback(comment) { _this.createCommentSuccessCallback(comment, uuid, _successCallback8); }, errorCallback: function errorCallback(e, code) { _this.createCommentErrorCallback(e, code, uuid); } })); }); _defineProperty(_assertThisInitialized(_this), "updateComment", function (file, commentId, text, hasMention, permissions, _successCallback9, errorCallback) { var commentData = { tagged_message: text }; if (!file.id) { throw getBadItemError(); } _this.file = file; _this.errorCallback = errorCallback; _this.updateFeedItem(_objectSpread({}, commentData, { isPending: true }), commentId); var message = {}; if (hasMention) { message.tagged_message = text; } else { message.message = text; } _this.commentsAPI = new CommentsAPI(_this.options); _this.commentsAPI.updateComment(_objectSpread({ file: file, commentId: commentId, permissions: permissions }, message, { successCallback: function successCallback(comment) { // use the request payload instead of response in the // feed item update because response may not contain // the tagged version of the message _this.updateFeedItem(_objectSpread({}, message, { isPending: false }), commentId); if (!_this.isDestroyed()) { _successCallback9(comment); } }, errorCallback: function errorCallback(e, code) { _this.feedErrorCallback(true, e, code); } })); }); _defineProperty(_assertThisInitialized(_this), "deleteAppActivity", function (file, appActivityId, successCallback, errorCallback) { var id = file.id; if (!id) { throw getBadItemError(); } _this.appActivityAPI = new AppActivityAPI(_this.options); _this.file = file; _this.errorCallback = errorCallback; _this.updateFeedItem({ isPending: true }, appActivityId); _this.appActivityAPI.deleteAppActivity({ id: id, appActivityId: appActivityId, successCallback: _this.deleteFeedItem.bind(_assertThisInitialized(_this), appActivityId, successCallback), errorCallback: function errorCallback(e, code) { _this.deleteAppActivityErrorCallback(e, code, appActivityId); } }); }); _defineProperty(_assertThisInitialized(_this), "deleteAppActivityErrorCallback", function (e, code, id) { _this.updateFeedItem(_this.createFeedError(messages.appActivityDeleteErrorMessage), id); _this.feedErrorCallback(true, e, code); }); _this.taskAssignmentsAPI = []; _this.taskCollaboratorsAPI = []; _this.taskLinksAPI = []; return _this; } /** * Creates a key for the cache * * @param {string} id folder id * @return {string} key */ _createClass(Feed, [{ key: "getCacheKey", value: function getCacheKey(id) { return "".concat(TYPED_ID_FEED_PREFIX).concat(id); } /** * Gets the items from the cache * * @param {string} id the cache id */ }, { key: "getCachedItems", value: function getCachedItems(id) { var cache = this.getCache(); var cacheKey = this.getCacheKey(id); return cache.get(cacheKey); } /** * Sets the items in the cache * * @param {string} id - the cache id * @param {Array} items - the feed items to cache */ }, { key: "setCachedItems", value: function setCachedItems(id, items) { var cache = this.getCache(); var cacheKey = this.getCacheKey(id); cache.set(cacheKey, { hasError: !!this.hasError, items: items }); } /** * Gets the feed items * * @param {BoxItem} file - The file to which the task is assigned * @param {boolean} shouldRefreshCache - Optionally updates the cache * @param {Function} successCallback - the success callback which is called after data fetching is complete * @param {Function} errorCallback - the error callback which is called after data fetching is complete if there was an error * @param {Function} onError - the function to be called immediately after an error occurs * @param {boolean} shouldShowNewTasks - feature flip the new tasks api * @param {boolean} shouldShowAppActivity - feature flip the new app activity api */ }, { key: "feedItems", value: function (_feedItems) { function feedItems(_x, _x2, _x3, _x4, _x5) { return _feedItems.apply(this, arguments); } feedItems.toString = function () { return _feedItems.toString(); }; return feedItems; }(function (file, shouldRefreshCache, successCallback, errorCallback, onError) { var _this2 = this; var shouldShowNewTasks = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; var shouldShowAppActivity = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; var id = file.id, _file$permissions = file.permissions, permissions = _file$permissions === void 0 ? {} : _file$permissions; var cachedItems = this.getCachedItems(id); if (cachedItems) { var hasError = cachedItems.hasError, items = cachedItems.items; if (hasError) { errorCallback(items); } else { successCallback(items); } if (!shouldRefreshCache) { return; } } this.file = file; this.hasError = false; this.errorCallback = onError; var versionsPromise = this.fetchVersions(); var currentVersionPromise = this.fetchCurrentVersion(); var commentsPromise = this.fetchComments(permissions); var tasksPromise = shouldShowNewTasks ? this.fetchTasksNew() : this.fetchTasks(); var appActivityPromise = shouldShowAppActivity ? this.fetchAppActivity(permissions) : Promise.resolve(); Promise.all([versionsPromise, currentVersionPromise, commentsPromise, tasksPromise, appActivityPromise]).then(function (_ref) { var _ref2 = _toArray(_ref), versions = _ref2[0], currentVersion = _ref2[1], feedItems = _ref2.slice(2); var versionsWithCurrent = _this2.versionsAPI.addCurrentVersion(currentVersion, versions, _this2.file); var sortedFeedItems = sortFeedItems.apply(void 0, [versionsWithCurrent].concat(_toConsumableArray(feedItems))); if (!_this2.isDestroyed()) { _this2.setCachedItems(id, sortedFeedItems); if (_this2.hasError) { errorCallback(sortedFeedItems); } else { successCallback(sortedFeedItems); } } }); }) /** * Fetches the comments for a file * * @param {Object} permissions - the file permissions * @return {Promise} - the file comments */ }, { key: "fetchComments", value: function fetchComments(permissions) { var _this3 = this; this.commentsAPI = new CommentsAPI(this.options); return new Promise(function (resolve) { _this3.commentsAPI.getComments(_this3.file.id, permissions, resolve, _this3.fetchFeedItemErrorCallback.bind(_this3, resolve)); }); } /** * Fetches the versions for a file * * @return {Promise} - the file versions */ }, { key: "fetchVersions", value: function fetchVersions() { var _this4 = this; this.versionsAPI = new VersionsAPI(this.options); return new Promise(function (resolve) { _this4.versionsAPI.getVersions(_this4.file.id, resolve, _this4.fetchFeedItemErrorCallback.bind(_this4, resolve)); }); } /** * Fetches the current version for a file * * @return {Promise} - the file versions */ }, { key: "fetchCurrentVersion", value: function fetchCurrentVersion() { var _this5 = this; this.versionsAPI = new VersionsAPI(this.options); return new Promise(function (resolve) { var _this5$file$file_vers = _this5.file.file_version, file_version = _this5$file$file_vers === void 0 ? {} : _this5$file$file_vers; _this5.versionsAPI.getCurrentVersion(_this5.file.id, file_version.id, resolve, _this5.fetchFeedItemErrorCallback.bind(_this5, resolve)); }); } /** * Fetches the tasks for a file * * @return {Promise} - the feed items */ }, { key: "fetchTasks", value: function fetchTasks() { var _this6 = this; this.tasksAPI = new TasksAPI(this.options); return new Promise(function (resolve) { _this6.tasksAPI.getTasks(_this6.file.id, function (tasks) { _this6.fetchTaskAssignments(tasks).then(resolve); }, _this6.fetchFeedItemErrorCallback.bind(_this6, resolve)); }); } /** * Fetches the tasks for a file * * @return {Promise} - the feed items */ }, { key: "fetchTasksNew", value: function fetchTasksNew() { var _this7 = this; this.tasksNewAPI = new TasksNewAPI(this.options); return new Promise(function (resolve) { _this7.tasksNewAPI.getTasksForFile({ file: { id: _this7.file.id }, successCallback: resolve, errorCallback: function errorCallback(err, code) { return _this7.fetchFeedItemErrorCallback(resolve, err, code); } }); }); } /** * Error callback for fetching feed items. * Should only call the error callback if the response is a 401, 429 or >= 500 * * @param {Function} resolve - the function which will be called on error * @param {Object} e - the axios error * @param {string} code - the error code * @return {void} */ }, { key: "fetchFeedItemErrorCallback", value: function fetchFeedItemErrorCallback(resolve, e, code) { var status = e.status; var shouldDisplayError = isUserCorrectableError(status); this.feedErrorCallback(shouldDisplayError, e, code); resolve(); } /** * Updates a task assignment * * @param {BoxItem} file - The file to which the task is assigned * @param {string} taskId - ID of task to be updated * @param {string} taskAssignmentId - Task assignment ID * @param {TaskAssignmentStatus} taskStatus - New task assignment status * @param {Function} successCallback - the function which will be called on success * @param {Function} errorCallback - the function which will be called on error * @return {void} */ }, { key: "createTaskSuccessCallback", /** * Callback for successful creation of a Task. Creates a task assignment * * @param {BoxItem} file - The file to which the task is assigned * @param {string} id - ID of the feed item to update with the new task data * @param {Task} task - API returned task * @param {Array} assignees - List of assignees * @param {Function} successCallback - the function which will be called on success * @param {Function} errorCallback - the function which will be called on error * * @return {void} */ value: function createTaskSuccessCallback(file, id, task, assignees, successCallback, errorCallback) { var _this8 = this; if (!file) { throw getBadItemError(); } this.errorCallback = errorCallback; var assignmentPromises = assignees.map(function (assignee) { return _this8.createTaskAssignment(file, task, assignee); }); Promise.all(assignmentPromises).then(function (taskAssignments) { var formattedTask = _this8.appendAssignmentsToTask(task, taskAssignments); _this8.updateFeedItem(_objectSpread({}, formattedTask, { isPending: false }), id); successCallback(task); }, function (e) { _this8.feedErrorCallback(false, e, ERROR_CODE_CREATE_TASK_ASSIGNMENT); }); } /** * Creates a task. * * @param {BoxItem} file - The file to which the task is assigned * @param {Object} currentUser - the user who performed the action * @param {string} message - Task text * @param {Array} assignees - List of assignees * @param {number} dueAt - Task's due date * @param {Function} successCallback - the function which will be called on success * @param {Function} errorCallback - the function which will be called on error * @return {void} */ }, { key: "createTaskNewSuccessCallback", /** * Callback for successful creation of a Task. Creates a task assignment * * @param {BoxItem} file - The file to which the task is assigned * @param {string} id - ID of the feed item to update with the new task data * @param {Task} task - API returned task * @param {Array} assignees - List of assignees * @param {Function} successCallback - the function which will be called on success * @param {Function} errorCallback - the function which will be called on error * * @return {void} */ value: function () { var _createTaskNewSuccessCallback = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(file, id, task, assignees, successCallback, errorCallback) { var _this9 = this; var taskLink, taskAssignments; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (file) { _context.next = 2; break; } throw getBadItemError(); case 2: this.errorCallback = errorCallback; _context.prev = 3; _context.next = 6; return this.createTaskLink(file, task); case 6: taskLink = _context.sent; _context.next = 9; return Promise.all(assignees.map(function (assignee) { return _this9.createTaskCollaborator(file, task, assignee); })); case 9: taskAssignments = _context.sent; this.updateFeedItem(_objectSpread({}, task, { task_links: { entries: [taskLink], next_marker: null, limit: 1 }, assigned_to: { entries: taskAssignments, next_marker: null, limit: taskAssignments.length }, isPending: false }), id); successCallback(task); _context.next = 17; break; case 14: _context.prev = 14; _context.t0 = _context["catch"](3); this.feedErrorCallback(false, _context.t0, ERROR_CODE_CREATE_TASK); case 17: case "end": return _context.stop(); } } }, _callee, this, [[3, 14]]); })); return function createTaskNewSuccessCallback(_x6, _x7, _x8, _x9, _x10, _x11) { return _createTaskNewSuccessCallback.apply(this, arguments); }; }() /** * Creates a task assignment via the API. * * @param {BoxItem} file - The file to which the task is assigned * @param {Task} task - The newly created task from the API * @param {SelectorItem} assignee - The user assigned to this task * @param {Function} errorCallback - Task create error callback * @return {Promise<TaskAssignment} */ }, { key: "createTaskAssignment", value: function createTaskAssignment(file, task, assignee) { var _this10 = this; if (!file.id) { throw getBadItemError(); } this.file = file; return new Promise(function (resolve, reject) { var taskAssignmentsAPI = new TaskAssignmentsAPI(_this10.options); _this10.taskAssignmentsAPI.push(taskAssignmentsAPI); taskAssignmentsAPI.createTaskAssignment({ file: file, taskId: task.id, assignTo: { id: assignee.id }, successCallback: function successCallback(taskAssignment) { resolve(taskAssignment); }, errorCallback: function errorCallback(e) { // Attempt to delete the task due to it's bad assignment _this10.deleteTask(file, task.id); reject(e); } }); }); } /** * Creates a task collaborator via the API. * * @param {BoxItem} file - The file to which the task is assigned * @param {Task|TaskUpdatePayload} task - The newly created or existing task from the API * @param {SelectorItem} assignee - The user assigned to this task * @param {Function} errorCallback - Task create error callback * @return {Promise<TaskAssignment>} */ }, { key: "createTaskCollaborator", value: function createTaskCollaborator(file, task, assignee) { var _this11 = this; if (!file.id) { throw getBadItemError(); } this.file = file; return new Promise(function (resolve, reject) { var taskCollaboratorsAPI = new TaskCollaboratorsAPI(_this11.options); _this11.taskCollaboratorsAPI.push(taskCollaboratorsAPI); taskCollaboratorsAPI.createTaskCollaborator({ file: file, task: task, user: assignee, successCallback: resolve, errorCallback: function errorCallback(e) { reject(e); } }); }); } /** * Deletes a task collaborator via the API. * * @param {BoxItem} file - The file to which the task is assigned * @param {Task|TaskUpdatePayload} task - The newly deleted or existing task from the API * @param {TaskCollabAssignee} assignee - The user assigned to this task * @param {Function} errorCallback - Task delete error callback * @return {Promise<TaskAssignment>} */ }, { key: "deleteTaskCollaborator", value: function deleteTaskCollaborator(file, task, assignee) { var _this12 = this; if (!file.id) { throw getBadItemError(); } this.file.id = file.id; return new Promise(function (resolve, reject) { var taskCollaboratorsAPI = new TaskCollaboratorsAPI(_this12.options); _this12.taskCollaboratorsAPI.push(taskCollaboratorsAPI); taskCollaboratorsAPI.deleteTaskCollaborator({ file: file, task: task, taskCollaborator: { id: assignee.id }, successCallback: resolve, errorCallback: function errorCallback(e) { reject(e); } }); }); } /** * Creates a task link via the API. * * @param {BoxItem} file - The file to which the task is assigned * @param {Task} task - The newly created task from the API * @param {Function} errorCallback - Task create error callback * @return {Promise<TaskAssignment} */ }, { key: "createTaskLink", value: function createTaskLink(file, task) { var _this13 = this; if (!file.id) { throw getBadItemError(); } this.file = file; return new Promise(function (resolve, reject) { var taskLinksAPI = new TaskLinksAPI(_this13.options); _this13.taskLinksAPI.push(taskLinksAPI); taskLinksAPI.createTaskLink({ file: file, task: task, successCallback: resolve, errorCallback: reject }); }); } /** * Deletes a task * * @param {BoxItem} file - The file to which the task is assigned * @param {string} taskId - The task's id * @param {Function} successCallback - the function which will be called on success * @param {Function} errorCallback - the function which will be called on error * @return {void} */ }, { key: "fetchTaskAssignments", /** * Fetches the task assignments for each task * * @param {Array} tasksWithoutAssignments - Box tasks * @return {Promise} */ value: function fetchTaskAssignments(tasksWithoutAssignments) { var _this14 = this; var entries = tasksWithoutAssignments.entries; var assignmentPromises = entries.map(function (task) { return new Promise(function (resolve) { var tasksAPI = new TasksAPI(_this14.options); _this14.taskAssignmentsAPI.push(tasksAPI); tasksAPI.getAssignments(_this14.file.id, task.id, function (assignments) { var formattedTask = _this14.appendAssignmentsToTask(task, assignments.entries); resolve(formattedTask); }, _this14.fetchFeedItemErrorCallback.bind(_this14, resolve)); }); }); var formattedTasks = { total_count: 0, entries: [] }; return Promise.all(assignmentPromises).then(function (assignments) { assignments.forEach(function (task) { if (task) { formattedTasks.entries.push(task); formattedTasks.total_count += 1; } }); return formattedTasks; }, function () { return formattedTasks; }); } /** * Formats assignments, and then adds them to their task. * * @param {Task} task - Task to which the assignments belong * @param {Task} assignments - List of task assignments * @return {Task} */ }, { key: "appendAssignmentsToTask", value: function appendAssignmentsToTask(task, assignments) { if (!assignments) { return task; } task.task_assignment_collection.entries = assignments.map(function (taskAssignment) { var id = taskAssignment.id, assigned_to = taskAssignment.assigned_to, status = taskAssignment.status; return { type: TASK_ASSIGNMENT, id: id, assigned_to: assigned_to, status: status }; }); // Increment the assignment collection count by the number of new assignments task.task_assignment_collection.total_count += assignments.length; return task; } /** * Add a placeholder pending feed item. * * @param {string} id - the file id * @param {Object} currentUser - the user who performed the action * @param {Object} itemBase - Base properties for item to be added to the feed as pending. * @return {void} */ }, { key: "createFeedError", /** * Constructs an error object that renders to an inline feed error * * @param {string} message - The error message body. * @param {string} title - The error message title. * @return {Object} An error message object */ value: function createFeedError(message) { var title = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : commonMessages.errorOccured; return { error: { message: message, title: title } }; } /** * Replace a