Home Reference Source

application/services/assignment-service.js

import Immutable from 'immutable';

import alt from './../alt';
import Alt from 'alt';
import BaseService from './base-service';
import {ErrorService} from './error-service';

import {parseSrn} from './../util/strings';
import {info} from './../util/console';

/**
 * Interact with assignment API service
 */
class AssignmentService extends BaseService {

    updateAssignment(assignment) {
        return assignment;
    }

    updateAssignments(assignment) {
        return assignment;
    }

    updatePagination(pagination) {
        return pagination;
    }

    /**
     * Remove (delete) assignment item
     * @param  {string} id
     */
    remove(id) {
        return (dispatch) => {
            return this.delete('/v3/assignment/' + id)
                .then(() => {
                    info(arguments);
                })
                .catch((e) => {
                    ErrorService.add('error', 'Unable to delete assignment, usually this means you don\'t have permission to remove items.');
                });
        };
    }

    /**
     * Update existing assignment item
     * @param  {string}   id       UUID
     * @param  {object}   data     Hash of assignment data
     * @param  {Function} callback
     */
    update(id, data, callback) {
        return (dispatch) => {
            return this.put('/v3/assignment/' + id, data)
                .then((data) => {
                    info('Update returned', data);
                    this.updateAssignment(data.first());
                    if (callback) {
                        callback(data.first());
                    }
                })
                .catch((e) => {
                    ErrorService.add('error', 'Unable to save assignment, usually this means you don\'t have it checked out.');
                });
        }
    }

    /**
     * Create new assignment item
     * @param  {object}   data     Hash of content data
     * @param  {Function} callback
     */
    create(data, callback) {
        return (dispatch) => {
            return this.post('/v3/assignment/', data)
                .then((data) => {
                    info('Create returned', data);
                    this.updateAssignment(data.first());
                    if (callback) {
                        callback(data.first());
                    }
                })
                .catch((e) => {
                    ErrorService.add('error', 'Unable to save assignment, usually this means you don\'t have it checked out.');
                });
        };
    }

    /**
     * Attempt to obtain a assignment lock, then update the assignment store
     * @param  {string} srn valid SRN
     */
    checkoutAndFetch(srn) {
        return (dispatch) => {
            return this.post('/v3/lock-request', {'srn': srn})
                .then((data) => {
                    info('Checkout and Fetch returned', data);
                    const parsedSrn = parseSrn(srn);
                    this.fetchOne(parsedSrn.uuid, {}, false);
                });
        };
    }

    /**
     * Attempt to release a assignment lock, then update assignment store
     * @param  {string} assignmentId assignment UUID
     * @param  {string} lockId    Lock UUID
     */
    checkinAndFetch(assignmentId, lockId) {
        return (dispatch) => {
            return this.delete('/v3/lock-request/' + lockId)
                .then((data) => {
                    info('Checkin and fetch returned', data);
                    this.fetchOne(assignmentId, {}, false);
                });
        };
    }

    /**
     * Fetch single assignment update
     * @param  {string}  id          UUID
     * @param  {object}  opts        Hash of query options
     * @param  {Boolean} forceUpdate If true (default) force update to assignment store, otherwise, don't
     */
    fetchOne(id, opts, forceUpdate = true) {
        if (forceUpdate === true) {
            this.updateAssignment([]);
        }
        return (dispatch) => {
            return this.get('/v3/assignment/' + id, opts)
                .then((data) => {
                    info('FetchOne returned', data);
                    this.updateAssignment(data.first());
                });
        };
    }

    /**
     * Fetch paginated assignment items
     * @param  {object} opts Hash of query options
     */
    fetch(opts) {
        return (dispatch) => {
            return this.get('/v3/assignment', opts)
                .then((data) => {
                    info('Fetch returned', data);
                    this.updatePagination(Immutable.fromJS({
                        'first': data.get('first'),
                        'before': data.get('before'),
                        'current': data.get('current'),
                        'last': data.get('last'),
                        'next': data.get('next'),
                        'total_pages': data.get('total_pages'),
                        'total_items': data.get('total_items'),
                        'limit': data.get('limit')
                    }));
                    
                    if (data.get('items').size) {
                        this.updateAssignments(data.get('items'))
                    } else {
                        this.updateAssignments(Immutable.fromJS([]));
                    }
                });
        };
    }

    /**
     * Run a query on the search endpoint. See search docs for query info
     * @param  {object} opts Query has
     */
    search(opts) {
        return (dispatch) => {
            return this.get('/v3/search', opts)
                .then((data) => {
                    info('Search returned', data);
                    this.updatePagination(Immutable.fromJS({
                        'first': data.get('first'),
                        'before': data.get('before'),
                        'current': data.get('current'),
                        'last': data.get('last'),
                        'next': data.get('next'),
                        'total_pages': data.get('total_pages'),
                        'total_items': data.get('total_items'),
                        'limit': data.get('limit')
                    }));

                    this.updateContents(data.get('items'))
                });
        };
    }

}

const service = alt.createActions(AssignmentService);

/**
 * Assignment Flux store. Tracks
 * <ul>
 *     <li>assignment</li>
 *     <li>assignments</li>
 *     <li>pagination</li>
 * </ul>
 */
class AssignmentsStore {
    constructor() {
        this.state = {
            'assignment': Immutable.Map(),
            'assignments': Immutable.Map(),
            'pagination': Immutable.Map()
        };

        this.bindListeners({
            'handleUpdateAssignment': service.UPDATE_ASSIGNMENT,
            'handleUpdateAssignments': service.UPDATE_ASSIGNMENTS,
            'handleUpdatePagination': service.UPDATE_PAGINATION
        });
    }

    handleUpdateAssignment(assignment) {
        this.setState({'assignment': assignment});
    }

    handleUpdateAssignments(assignment) {
        this.setState({'assignments': assignment});
    }

    handleUpdatePagination(pagination) {
        this.setState({'pagination': pagination});
    }
}

const store = alt.createStore(AssignmentsStore, 'AssignmentsStore');

/**
 * Instace wrapper if you don't or can't use the singleton action and classes.
 *
 * Actions and store are both under the 'assignments' key.
 */
class AssignmentFlux extends Alt {
    constructor(config = {}) {
        super(config);

        this.addActions('assignments', AssignmentService);
        this.addStore('assignments', AssignmentsStore);
    }
}

export {AssignmentFlux as default, service as AssignmentService, store as AssignmentsStore};