Source: managers/tasks.ts

/**
 * @fileoverview Manager for the Tasks Resource
 */

// -----------------------------------------------------------------------------
// Requirements
// -----------------------------------------------------------------------------

import BoxClient from '../box-client';
import urlPath from '../util/url-path';

// -----------------------------------------------------------------------------
// Typedefs
// -----------------------------------------------------------------------------

/**
 * Enum of valid task resolution states
 * @readonly
 * @enum {TaskResolutionState}
 */
enum TaskResolutionState {
  COMPLETE = 'completed',
  INCOMPLETE = 'incomplete',
  APPROVED = 'approved',
  REJECTED = 'rejected',
}

// -----------------------------------------------------------------------------
// Private
// -----------------------------------------------------------------------------

const BASE_PATH = '/tasks',
  ASSIGNMENTS_SUBRESOURCE = 'assignments',
  ASSIGNMENTS_PATH = '/task_assignments',
  REVIEW_ACTION = 'review';

// -----------------------------------------------------------------------------
// Public
// -----------------------------------------------------------------------------

/**
 * Simple manager for interacting with all 'Tasks' endpoints and actions.
 *
 * @constructor
 * @param {BoxClient} client - The Box API Client that is responsible for making calls to the API
 * @returns {void}
 */
class Tasks {
  client: BoxClient;

  resolutionStates!: typeof TaskResolutionState;

  constructor(client: BoxClient) {
    this.client = client;
  }

  /**
   * Used to create a single task for single user on a single file.
   *
   * API Endpoint: '/tasks'
   * Method: POST
   *
   * @param {string} fileID - The ID of the item this task is for
   * @param {Object} [options] - Additional parameters
   * @param {string} [options.message] - An optional message to include with the task
   * @param {string} [options.due_at] - The day at which this task is due
   * @param {Function} [callback] - Passed the new task information if it was acquired successfully, error otherwise
   * @returns {Promise<Object>} A promise resolving to the created task object
   */
  create(
    fileID: string,
    options?: {
      message?: string;
      due_at?: string;
    },
    callback?: Function
  ) {
    var apiPath = urlPath(BASE_PATH),
      params = {
        body: {
          item: {
            type: 'file',
            id: fileID,
          },
          action: REVIEW_ACTION,
        },
      };

    Object.assign(params.body, options);

    return this.client.wrapWithDefaultHandler(this.client.post)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Fetches a specific task.
   *
   * API Endpoint: '/tasks/:taskID'
   * Method: GET
   *
   * @param {string} taskID - The Box ID of the task being requested
   * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
   * @param {Function} [callback] - Passed the task information if it was acquired successfully, error otherwise
   * @returns {Promise<Object>} A promise resolving to the task object
   */
  get(taskID: string, options?: Record<string, any>, callback?: Function) {
    var apiPath = urlPath(BASE_PATH, taskID),
      params = {
        qs: options,
      };

    return this.client.wrapWithDefaultHandler(this.client.get)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Updates a specific task.
   *
   * API Endpoint: '/tasks/:taskID'
   * Method: PUT
   *
   * @param {string} taskID - The Box ID of the task being updated
   * @param {Object} updates - Fields of the task object to update
   * @param {string} [updates.message] - An optional message to include with the task
   * @param {string} [updates.due_at] - The day at which this task is due
   * @param {Function} [callback] - Passed the updated task information if it was acquired successfully, error otherwise
   * @returns {Promise<Object>} A promise resolving to the updated task object
   */
  update(
    taskID: string,
    updates?: {
      message?: string;
      due_at?: string;
    },
    callback?: Function
  ) {
    var apiPath = urlPath(BASE_PATH, taskID),
      params = {
        body: updates,
      };

    return this.client.wrapWithDefaultHandler(this.client.put)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Permanently deletes a specific task.
   *
   * API Endpoint: '/tasks/:taskID'
   * Method: DELETE
   *
   * @param {string} taskID - The Box ID of the task being deleted
   * @param {Function} [callback] - Empty body passed if successful, error otherwise
   * @returns {Promise<void>} A promise resolving to nothing
   */
  delete(taskID: string, callback?: Function) {
    var apiPath = urlPath(BASE_PATH, taskID);

    return this.client.wrapWithDefaultHandler(this.client.del)(
      apiPath,
      null,
      callback
    );
  }

  /**
   * Get a list of assignments for a given task
   *
   * API Endpoint: '/tasks/:taskID/assignments'
   * Method: GET
   *
   * @param {string} taskID - The Box ID of the task to get assignments for
   * @param {Object} [options] - Additional parameters, can be left null in most cases
   * @param {Function} [callback] - Passed the list of assignments if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to the collection of assignment objects
   */
  getAssignments(
    taskID: string,
    options?: Record<string, any>,
    callback?: Function
  ) {
    var apiPath = urlPath(BASE_PATH, taskID, ASSIGNMENTS_SUBRESOURCE),
      params = {
        qs: options,
      };

    return this.client.wrapWithDefaultHandler(this.client.get)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Get a specific task assignment
   *
   * API Endpoint: '/task_assignments/:assignmentID'
   * Method: GET
   *
   * @param {string} assignmentID - The Box ID of the task assignment to retrieve
   * @param {Object} [options] - Additional parameters, can be left null in most cases
   * @param {Function} [callback] - Passed the task assignment if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to the assignment object
   */
  getAssignment(
    assignmentID: string,
    options?: Record<string, any>,
    callback?: Function
  ) {
    var apiPath = urlPath(ASSIGNMENTS_PATH, assignmentID),
      params = {
        qs: options,
      };

    return this.client.wrapWithDefaultHandler(this.client.get)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Assign a task to a specific user by ID
   *
   * API Endpoint: '/task_assignments'
   * Method: POST
   *
   * @param {string} taskID - The Box ID of the task to assign
   * @param {string} userID - The ID of the user to assign the task to
   * @param {Function} [callback] - Passed the task assignment if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to the new assignment object
   */
  assignByUserID(taskID: string, userID: string, callback?: Function) {
    var apiPath = urlPath(ASSIGNMENTS_PATH),
      params = {
        body: {
          task: {
            type: 'task',
            id: taskID,
          },
          assign_to: {
            id: userID,
          },
        },
      };

    return this.client.wrapWithDefaultHandler(this.client.post)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Assign a task to a specific user by email address
   *
   * API Endpoint: '/task_assignments'
   * Method: POST
   *
   * @param {string} taskID - The Box ID of the task to assign
   * @param {string} email - The email address of the user to assign the task to
   * @param {Function} [callback] - Passed the task assignment if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to the new assignment object
   */
  assignByEmail(taskID: string, email: string, callback?: Function) {
    var apiPath = urlPath(ASSIGNMENTS_PATH),
      params = {
        body: {
          task: {
            type: 'task',
            id: taskID,
          },
          assign_to: {
            login: email,
          },
        },
      };

    return this.client.wrapWithDefaultHandler(this.client.post)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Update a task assignment.  This is used to resolve or complete a task.
   *
   * API Endpoint: '/task_assignments/:assignmentID'
   * Method: PUT
   *
   * @param {string} assignmentID - The Box ID of the task assignment to update
   * @param {Object} options - The fields of the assignment to update
   * @param {string} [options.message] - A message from the assignee about this task
   * @param {TaskResolutionState} [options.resolution_state] - Resolution of the task
   * @param {Function} [callback] - Passed the updated task assignment if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to the updated assignment object
   */
  updateAssignment(
    assignmentID: string,
    options?: {
      message?: string;
      resolution_state?: TaskResolutionState;
    },
    callback?: Function
  ) {
    var apiPath = urlPath(ASSIGNMENTS_PATH, assignmentID),
      params = {
        body: options,
      };

    return this.client.wrapWithDefaultHandler(this.client.put)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Delete a task assignment.  This unassigns a user from the related task.
   *
   * API Endpoint: '/task_assignments/:assignmentID'
   * Method: DELETE
   *
   * @param {string} assignmentID - The Box ID of the task assignment to delete
   * @param {Function} [callback] - Passed nothing if successful, error otherwise
   * @returns {Promise<void>} A promise resolving to nothing
   */
  deleteAssignment(assignmentID: string, callback?: Function) {
    var apiPath = urlPath(ASSIGNMENTS_PATH, assignmentID);

    return this.client.wrapWithDefaultHandler(this.client.del)(
      apiPath,
      null,
      callback
    );
  }
}

/**
 * Enum of valid task resolution states
 * @readonly
 * @enum {TaskResolutionState}
 */
Tasks.prototype.resolutionStates = TaskResolutionState;

export = Tasks;