application/services/content-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 content API service
*/
class ContentService extends BaseService {
updateContent(content) {
return content;
}
updateContents(content) {
return content;
}
updatePagination(pagination) {
return pagination;
}
/**
* Remove (delete) content item
* @param {string} id
*/
remove(id) {
return (dispatch) => {
return this.delete('/v3/content/' + id)
.then(() => {
info(arguments);
})
.catch((e) => {
ErrorService.add('error', 'Unable to delete content, usually this means you don\'t have permission to remove items.');
});
};
}
/**
* Update existing content item
* @param {string} id UUID
* @param {object} data Hash of content data
* @param {Function} callback
*/
update(id, data, callback) {
return (dispatch) => {
return this.put('/v3/content/' + id, data)
.then((data) => {
info('Update returned', data);
this.updateContent(data.first());
if (callback) {
callback(data.first());
}
})
.catch((e) => {
ErrorService.add('error', 'Unable to save item, usually this means you don\'t have it checked out.');
});
}
}
/**
* Create new content item
* @param {object} data Hash of content data
* @param {Function} callback
*/
create(data, callback) {
return this.post('/v3/content/', data)
.then((data) => {
info('Create returned', data);
this.updateContent(data.first());
if (callback) {
callback(data.first());
}
return data;
});
}
upload(data, callback) {
return this.postUpload('/v3/content/', data)
.then((data) => {
info('Create returned', data);
this.updateContent(data.first());
if (callback) {
callback(data.first());
}
return data;
});
}
/**
* Attempt to obtain a content lock, then update the content 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 content lock, then update content store
* @param {string} contentId Content UUID
* @param {string} lockId Lock UUID
*/
checkinAndFetch(contentId, lockId) {
return (dispatch) => {
return this.delete('/v3/lock-request/' + lockId)
.then((data) => {
info('Checkon and fetch returned', data);
this.fetchOne(contentId, {}, false);
});
};
}
/**
* Fetch single content update
* @param {string} id UUID
* @param {object} opts Hash of query options
* @param {Boolean} forceUpdate If true (default) force update to content store, otherwise, don't
*/
fetchOne(id, opts, forceUpdate = true) {
if (forceUpdate === true) {
this.updateContent([]);
}
return (dispatch) => {
return this.get('/v3/content/' + id, opts)
.then((data) => {
info('FetchOne returned', data);
this.updateContent(data.first());
});
};
}
/**
* Fetch paginated content items
* @param {object} opts Hash of query options
*/
fetch(opts) {
return (dispatch) => {
return this.get('/v3/content', 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')
}));
this.updateContents(data.get('items'))
});
};
}
/**
* 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(ContentService);
/**
* Content Flux store. Tracks
* <ul>
* <li>content</li>
* <li>contents</li>
* <li>pagination</li>
* </ul>
*/
class ContentsStore {
constructor() {
this.state = {
'content': Immutable.Map(),
'contents': Immutable.Map(),
'pagination': Immutable.Map()
};
this.bindListeners({
'handleUpdateContent': service.UPDATE_CONTENT,
'handleUpdateContents': service.UPDATE_CONTENTS,
'handleUpdatePagination': service.UPDATE_PAGINATION
});
}
handleUpdateContent(content) {
this.setState({'content': content});
}
handleUpdateContents(content) {
this.setState({'contents': content});
}
handleUpdatePagination(pagination) {
this.setState({'pagination': pagination});
}
}
const store = alt.createStore(ContentsStore, 'ContentsStore');
/**
* Instace wrapper if you don't or can't use the singleton action and classes.
*
* Actions and store are both under the 'contents' key.
*/
class ContentFlux extends Alt {
constructor(config = {}) {
super(config);
this.addActions('contents', ContentService);
this.addStore('contents', ContentsStore);
}
}
export {ContentFlux as default, service as ContentService, store as ContentStore};