src/helpers/Section.js
import SectionModel from '../models/Section';
// import { serviceFactory } from '../utilities/factories/ServiceFactory';
import Helper from './Helper';
import { aggregate } from '../utilities/ClassUtility';
import FlowService from '../services/FlowService';
import StatusService from '../services/StatusService';
import { validate, hasToken, isRequired } from '../utilities/ValidationUtility';
/**
* Helper class representing a Section.
*/
class Section extends aggregate(SectionModel, Helper) {
/**
* Constructor for Section
*
* @param {!Object} response - Requires all fields that are necessary for SectionModel
*
* @return {Section} Returns a new Section instance
*/
constructor(response) {
super(response);
/** @type {String} */
this.type = this.type || 'sections';
/** @type {Object[]} */
this._sections = [];
// Map children to sections
if (response.sub_statuses) {
this.connectChildren(response.sub_statuses);
}
}
/** @type {String} - The type */
static get type() {
return 'sections';
}
/** @type {String} - The type */
get type() {
return this._type || 'sections';
}
/** @type {String} - The type */
set type(t) {
this._type = t;
}
/**
* Get Sections
*
* @return {Array<Object>} - Array of objects depending on the type of sub sections.
*/
get sections() {
return this._sections;
}
/**
* Get Status and set it to this.status
*
* @return {Promise} - A Promise containing the status (String)
*/
getStatus() {
validate('Section getStatus()',
hasToken(),
isRequired({
type: this.type,
object: this.object,
ownerType: this.ownerType,
owner: this.owner,
}));
return (new StatusService()).getStatus(
this.type,
this.object,
this.ownerType,
this.owner
).then(data => (this.status = data.status.value));
}
/**
* Synchronize Sections if the content is a section this will load sections belonging to it
*
* @return {Promise} - A Promise of an array of objects depending on the type of sub sections.
*/
getChildren() {
validate('Section getChildren()',
hasToken(),
isRequired({
owner: this.owner,
ownerType: this.ownerType,
name: this.object,
}));
const { object: name, owner, ownerType } = this;
return (new StatusService()).getSections(name, ownerType, owner).then((d) => {
/** @type {String} */
this.status = d.section_status.value;
// copy over the section status array to 'section' and create data Object() if necessary
this.connectChildren(d.section_status.sub_statuses);
return this._sections;
});
}
/**
* Gets the data depending on 'type' and the 'object' fields
*
* @return {Section}
*
* @memberOf Section
*/
getData() {
const section = this;
const { owner, ownerType } = section;
return new Promise((resolve, reject) => {
switch (section.type) {
case 'data_collection/flow_process':
(new FlowService()).getFlow(section.object).then((f) => {
section.data = f;
section.data.status = section.value;
section.data.options = { owner, ownerType };
resolve(section);
}).catch((reason) => {
reject(reason);
});
break;
case 'section':
// TODO add StatusService
// (new ContentService()).geContent(section.object).then(c => (section.data = c));
(new StatusService()).getSections(section.object, ownerType, owner).then((c) => {
section.data = c;
section.data.status = section.value;
section.data.label = section.label;
section.data.object = section.object;
resolve(section);
}).catch((reason) => {
reject(reason);
});
break;
default: // section.data = undefined;
resolve(null);
break;
}
});
}
/**
* Connects children and provides appropriate data elements in the data field. It is important
* to note that invalid children will only have Section wrappers but no data. This will not
* throw any errors when there is no data from the server. Check the network capability of
* the browser or developer tool (Charles etc) to find invalid calls.
*
* @param {Array<any>} childArray - should contain an array of deserialized Sections in JSON
*
* @memberOf Section
*/
connectChildren(childArray) {
const { owner, ownerType } = this;
this._sections = childArray.map((obj) => {
const section = new Section(Object.assign({}, { ownerType, owner }, obj));
// Get section information but skip over invalid children
section.getData().catch(() => {});
return section;
});
}
/**
* Transition between states using actions
*
* @param {String} action - The action must be a string like 'acknowledge'
*
* @return {Promise} Returns a promise but will alsoassign the new state to the Flow intance
*/
transition(action) {
return (new StatusService()).transition(
action,
this.type,
this.object,
this.ownerType,
this.owner
).then(data => (this.status = data.status.value));
}
}
export default Section;