Source: AWM-Control-TaskAPI.js

/**

 * @file SPARK - TaskAPI

 * @copyright {@link http://salientprocess.com|Salient Process, Inc} (2015)

 * @author Salient Process R&D Team

 */



/** 

 * @constructor TaskAPI

 * @desc This constructor is <i>never</i> used explicitly.

 * @augments com.ibm.bpm.coach.CoachView 

 * @classdesc A TaskAPI  control provides the following configuration properties in Process Designer:

 * <table class=Config>

 *   <tr class=Prop>

 *     <td class=SectionName colspan=3>Behavior</td>

 *   </tr>

 

 *   <tr class=Prop>

 *     <td>Data Retrieval Mode:</td>

 *     <td>{All Details | Data Only | Available Actions | None}</td>

 *     <td><code>string</code></td>

 *   </tr>



 *   <tr class=Prop>

 *     <td class=SectionName colspan=3>Events</td>

 *   </tr>

 

 *   <tr class=Prop>

 *     <td>On Load:</td>

 *	   <td colspan = "2">

 *       <table> 

 *         <tr class=Prop>

 *           <td>Description: </td>

 *           <td>This event when the control is loaded.</td>

 *         </tr>

 

 *         <tr class=Prop>

 *           <td>Example: </td>

 *           <td><pre class="prettyprint"><code><code></pre></td>

 *         </tr>

 *       </table>

 *     </td>

 *   </tr>

 

 *   <tr class=Prop>

 *     <td>On Request Complete:</td>

 *	   <td colspan = "2">

 *       <table> 

 *         <tr class=Prop>

 *           <td>Description: </td>

 *           <td>This event fires whenever a request is completed successfully.</td>

 *         </tr>

 

 *         <tr class=Prop>

 *           <td>Example: </td>

 *           <td><pre class="prettyprint"><code>${TaskUIFrame}.loadTask(me.getTaskId());<code></pre></td>

 *         </tr>

 *       </table>

 *     </td>

 *   </tr>

 

 *   <tr class=Prop>

 *     <td>On Request Error:</td>

 *	   <td colspan = "2">

 *       <table> 

 *         <tr class=Prop>

 *           <td>Description: </td>

 *           <td>This event is fired when a request error is detected.</td>

 *         </tr>

 

 *         <tr class=Prop>

 *           <td>Example: </td>

 *           <td><pre class="prettyprint"><code>console.log(me.getResult());<code></pre></td>

 *         </tr>

 *       </table>

 *     </td>

 *   </tr>

 * </table>

 */

awm_control_InitTaskAPI = function(bpmext, lang, json, xhr)

{

	this._instance = {

		_taskId: null,

	};



	if (!this.constructor.prototype._proto)

	{

		this.constructor.prototype._proto = {

			_onReqCompleteEvent: "eventON_REQ_COMPLETE",

			_onReqErrorEvent: "eventON_REQ_ERROR",

			_cleanObject: function(obj)

			{

				if (obj !== null && typeof(obj) == "object")

				{

					delete obj["@metadata"];



					for(var prop in obj) 

					{

						this._cleanObject(obj[prop]);

					}

				}

			},

			_objectAsList2: function(obj, parent, list)

			{

				for(var key in obj)

				{

					var val = obj[key];

					var tval = typeof val;

					var path = parent != null ? parent + "." + key : key;

					

					if(tval == null)

					{

						list.push({path: path, value: val});

					}

					else if (tval == "function")

					{

						continue;

					}

					else if(tval == "object" && !(val instanceof Date))

					{

						this._objectAsList2(val, path, list);

					}

					else

					{

						list.push({path: path, value: val});

					}

				}

			},

			_objectAsList: function(obj)

			{

				var list = [];

				this._objectAsList2(obj, null, list);

				

				return list;

			},

			_callAjaxService: function(view, args)

			{

				var url = args.url;

				var put = args.method == "put";

				var params = args.params;

				var queryData = "";

				

				for(var paramName in params)

				{

					var uriComponent = params[paramName];



					if(uriComponent != null)

					{

						if(queryData.length > 0)

							queryData +="&";

						

						if(typeof uriComponent == "object")

							uriComponent = json.stringify(uriComponent);

						

						queryData += (paramName + "=" + encodeURIComponent(uriComponent));

					}

				}

				

				bpmext.log.debug("REST query: " + queryData, view);

				

				var xhrArgs = 

				{

					url: url + "?" + queryData,

					handleAs: "json",

					headers: {

						"Content-Type": "application/x-www-form-urlencoded",

						"Accept": "application/json",

						},

					sync: false,

					load: function(res)

					{

						if ((!!args) && (!!(args.load)) && (lang.isFunction(args.load)))

						{

							if(res != null)

							{

								view._proto._cleanObject(res.data);

								res = res.data;

							}

							

							var response = {

								result: res

							};

							

							args.load(response);

						}

					},

					error: function(err) 

					{

						if ((!!args) && (!!(args.error)) && (lang.isFunction(args.error))) 

							args.error(err);

						else 

							bpmext.log.error("Error handling " + url + ", Error: " + err);

					}

				};

				

				if(put === true)

					xhr.put(xhrArgs);

				else

					xhr.get(xhrArgs);

			},

			_getDataRetrievalMode: function(view)

			{

				var drm = view.context.options.dataRetrievalMode.get("value");

				

				switch(drm)

				{

					case "A":

						drm = "all";

						break;

					case "D":

						drm = "data";

						break;

					case "C":

						drm = "actions";

						break;

					case "N":

						drm = "none";

				}



				return drm;

			},

			_exec: function(view, method, params, action)

			{

				var taskId = view.context.binding.get("value");

				

				if(taskId == null)

				{

					view._instance._taskError = {errorMessage: "No task id specified"};

					bpmext.ui.executeEventHandlingFunction(view, view._proto._onReqErrorEvent);

					

					return;

				}



				view._instance.lastAction = action;

				this._callAjaxService(

					view, 

					{

						url: "/rest/bpm/wle/v1/task/" + taskId,

						params: params,

						method: method,

						load: function(response)

						{

							if(response != null)

								view._instance._taskData = response.result;

							

							bpmext.ui.executeEventHandlingFunction(view, view._proto._onReqCompleteEvent);

						},

						error: function(error)

						{

							view._instance._taskError = error;

							bpmext.ui.executeEventHandlingFunction(view, view._proto._onReqErrorEvent);

						}

					}

				);				

			},

			_xhrGet: function(view, params, action)

			{

				this._exec(view, "get", params, action);

			},

			_xhrPut: function(view, params, action)

			{

				this._exec(view, "put", params, action);

			}

		};

		

		/*

		Public control methods *************************************************************

		*/		

		

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method getResult

		 * @desc Gets the data of task(s) 

		 * @returns {object}

		 */

		this.constructor.prototype.getResult = function()

		{

			return this._instance._taskData;

		}

		

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method getBusinessData

		 * @desc Gets the business data for the control

		 * @param {boolean} asList whether to return as a list or not

		 * @returns {object}

		 */

		this.constructor.prototype.getBusinessData = function(asList)

		{

			if (this._instance._taskData != null &&

				this._instance._taskData.data != null && 

				this._instance._taskData.data.variables != null

			)

			{

				if(asList)

					return this._proto._objectAsList(this._instance._taskData.data.variables);

				else

					return this._instance._taskData.data.variables;

			}

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method setBusinessData

		 * @desc Sets the business data for the control

		 * @param {string} data the data for the business data, note: data is a string which must be in JSON format

		 */

		this.constructor.prototype.setBusinessData = function(data)

		{

			this._proto._xhrPut(

				this, 

				{

					action: "setData",

					params: data

				},

				"SETDATA"

			);

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method start

		 * @desc Programmatically start the control

		 */

		this.constructor.prototype.start = function()

		{

			this._proto._xhrPut(

				this, 

				{

					action: "start"

				},

				"START"

			);

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method assignToUser

		 * @desc Assign the task to a user

		 * @param {string} user the name of the user

		 */

		this.constructor.prototype.assignToUser = function(user)

		{

			this._proto._xhrPut(

				this, 

				{

					action: "assign",

					parts: this._proto._getDataRetrievalMode(this),

					toUser: user

				},

				"ASSIGN:TO_USER"

			);

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method assignToGroup

		 * @desc Assign the task to a group

		 * @param {string} group the name of the group to which the task should be assigned.

		 */

		this.constructor.prototype.assignToGroup = function(group)

		{

			this._proto._xhrPut(

				this, 

				{

					action: "assign",

					parts: this._proto._getDataRetrievalMode(this),

					toGroup: group

				},

				"ASSIGN:TO_GROUP"

			);

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method assignToMe

		 * @desc Assigns the task to the individual that is running the instance.

		 */

		this.constructor.prototype.assignToMe = function()

		{

			this._proto._xhrPut(

				this, 

				{

					action: "assign",

					parts: this._proto._getDataRetrievalMode(this),

					toMe: true

				},

				"ASSIGN:TO_ME"

			);	

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method assignBack

		 * @desc Assigns the task back to the original owner.

		 */

		this.constructor.prototype.assignBack = function()

		{

			this._proto._xhrPut(

				this, 

				{

					action: "assign",

					parts: this._proto._getDataRetrievalMode(this),

					back: true

				},

				"ASSIGN:BACK"

			);			

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method updatePriority

		 * @desc Updates the priority of the task.

		 * @param {string} priority Highest/10 | High/20 | Normal/30 | Low/40 | Lowest/50

		 * @example ${TaskAPI}.updatePriority("10"); //sets the current tasks priority to "Highest"

		 */

		this.constructor.prototype.updatePriority = function(priority)

		{

			//Highest/10, High/20, Normal/30, Low/40 or Lowest/50

			if(isNaN(priority)) //Tolerate casing differences

			{

				priority = priority.charAt(0).toUpperCase() + priority.substring(1).toLowerCase();

			}



			this._proto._xhrPut(

				this, 

				{

					action: "update",

					parts: this._proto._getDataRetrievalMode(this),

					priority: priority

				},

				"UPDATE:PRIORITY"

			);	

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method updateDueDate

		 * @desc Updates the due date of the task

		 * @param {string} date due date is formatted in ISO-8601 format (e.g. 2011-01-05T03:15:30.000-00:00)

		 */			

		//Due date in ISO-8601 format (e.g. 2011-01-05T03:15:30.000-00:00)

		this.constructor.prototype.updateDueDate = function(dueDate)

		{

			if(typeof dueDate == "object")

				dueDate = dueDate.toISOString();



			this._proto._xhrPut(

				this, 

				{

					action: "update",

					parts: this._proto._getDataRetrievalMode(this),

					dueDate: dueDate

				},

				"UPDATE:DUE_DATE"

			);			

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method cancel

		 * @desc Programmatically cancels the task

		 * @param {string} date due date is formatted in ISO-8601 format (e.g. 2011-01-05T03:15:30.000-00:00)

		 */		

		this.constructor.prototype.cancel = function()

		{

			this._proto._xhrPut(

				this, 

				{

					action: "cancel"

				},

				"CANCEL"

			);			

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method finish

		 * @desc Mark the task as finished

		 * @param {string} data the passed in data

		 */		

		this.constructor.prototype.finish = function(data)

		{

			this._proto._xhrPut(

				this, 

				{

					action: "finish",

					parts: this._proto._getDataRetrievalMode(this),

					params: data

				},

				"FINISH"

			);

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method refresh

		 * @desc Refreshes the task to view changes and updates made

		 */		

		this.constructor.prototype.refresh = function()

		{

			this._proto._xhrGet(

				this, 

				{

					parts: this._proto._getDataRetrievalMode(this)

				},

				"REFRESH"

			);

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method setTaskId

		 * @desc Sets the task ID

		 * @param {integer}  taskId the assigned task ID

		 * @param {boolean} refresh whether or not to refresh

		 */		

		this.constructor.prototype.setTaskId = function (taskId, refresh)

		{

			this._instance.noRefresh = (refresh === false);

			this.context.binding.set("value", taskId);

			

			delete this._instance.noRefresh;

		}

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method getTaskId

		 * @desc Gets the task ID

		 * @returns {integer} 

		 */		

		this.constructor.prototype.getTaskId = function()

		{

			return this.context.binding.get("value");

		}



		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method getLastAction

		 * @desc Gets the last type of request made

		 * @returns {string} 

		 */	

		this.constructor.prototype.getLastAction = function ()

		{

			return this._instance.lastAction;

		}

		

		/**

		 * @instance

		 * @memberof TaskAPI

		 * @method getType

		 * @desc Gets the type of the control

		 * @returns {string} 

		 */	

		this.constructor.prototype.getType = function ()

		{

			return "taskAPI.4";

		}



		/*

		Coach NG Lifecycle methods *************************************************************

		 */

		this.constructor.prototype.load = function ()

		{

			try

			{

				bpmext.ui.registerEventHandlingFunction(this, this._proto._onReqCompleteEvent);

				bpmext.ui.registerEventHandlingFunction(this, this._proto._onReqErrorEvent);



				var opts = this.context.options;

				var mdt = opts._metadata;

				var view = this;

				

				if (!this.context.binding)

					this.context.binding = bpmext.ui.substituteObject(this);



				if (!opts.dataRetrievalMode)

					bpmext.ui.substituteConfigOption(this, "dataRetrievalMode", "A");

				

				bpmext.ui.loadView(this);



				this.refresh();

			}

			catch (e)

			{

				bpmext.log.error("Error on load event [" + this.context.viewid + "]: " + e);

				if(e.stack)

					bpmext.log.error("  Call stack: " + e.stack);

			}

		};



		this.constructor.prototype.view = function ()

		{

			try

			{



			}

			catch (e)

			{

				bpmext.log.error("Error on view event [" + this.ui.getAbsoluteName() + "]: " + e);

				if(e.stack)

					bpmext.log.error("  Call stack: " + e.stack);

			}

		};



		this.constructor.prototype.change = function (event)

		{

			try

			{

				if (event.type == "config") 

				{

					switch (event.property)

					{



					}

				} 

				else

				{

					delete this._instance._taskData;

					

					if(!this._instance.noRefresh && event.newVal != event.oldVal) 

					{

						this.refresh();

					}

				}

			}

			catch (e)

			{

				bpmext.log.error("Error on change event [" + this.ui.getAbsoluteName() + "]: " + e);

				if(e.stack)

					bpmext.log.error("  Call stack: " + e.stack);

			}

		};



		this.constructor.prototype.unload = function ()

		{

			bpmext.ui.unloadView(this);

		};

	}

}