Overriding an action - tsgrp/HPI GitHub Wiki

Overriding an action in HPI 2.2 has changed since the introduction of 'self-registering' actions. To override parts of an action now, we store the overridden part of the action on the action module when the action is registered. This then gets put on the action's config when the action is loaded in the app.

Before, the overrideable part of the action (function, attribute, etc) was stored on the action module. This is no longer the case. Now, it can just be a local param. Then, you should pass this as an attribute on the object you pass as the fourth parameter when you register the action. Then, when this needs to get used in the action's view model, you use it by calling it off of the config.


var MyAction = {};

var funcToOverride = function(param1){
   //does something
   if(param1){
      return true;
   }
   else{
      return false;
   }
};

function ViewModel(action, myHandler, config){
//...view model stuff...
   self.showEditView = config.funcToOverride(myParam);
//...more view model stuff...
};

//...view stuff would go here...

//now, here's how to register the action
actionModules.registerAction("myAction", MyAction, {
   "actionId" : "myAction",
   "label" : "My Action",
   "icon" : "comment",
   "handler" : "modalActionHandler"
},
//this is where we will put our overrideable function
{
   "funcToOverride" : funcToOverride
});

Note: For legacy support reasons, this final parameter is not required when registering an action. Therefore, you may need to make changes to the original action module to make it register an action correctly. You will want it to follow the format shown above. For examples, see folder notes and send email.

##Configuration##

In HPI 2.2, the way actions are brought into projects has changed to a project-specific model, where individual actions can be configured for a particular project, without affecting other client projects. We can override individual methods of an action, or even the entire action.

In project/your client/app/configs/config-project.js, you can create your own project-specific set of actions to override:

actions.*your project name* = {
  'overriddenActionName': "path to overridden action"
};

//push your new configuration onto the list of all hpi action configurations
activeActionPackages.push(*your project name*);

Note: Your overridden action must have a different name then the default action name. For example, if you wanted to override part of the Folder Notes action, your custom override can't be named FolderNotes as it will break the pathing. Instead, you might name it your project name + action name.

##Overridden Action##

Similar to a regular action, an overridden action requires a define array, a main function, and a require. In the function, you need to use the underscore extend function to override your function or attribute. You will return the result of this function. Before doing that, though, you will need to register your action. You will use a unique string name for the first parameter, but for the 'actionId' property in the third parameter, use the name of the action you are overriding. The fourth parameter is an object that contains the part of the action you are overriding. Here's a template:

//customActionName should be the same as the one defined in config-project.js
define("abbspiraFolderNotes",[
	//Dependencies
	"foldernotes", //the core action being overridden, look at config-actions.js for the exact name
	"modules/actions/actionmodules"
],
//main function
function(FolderNotes, actionModules) {
	"use strict";
	//set a local variable equal to the result of the underscore extend function
	//first param is an empty object, second is the original action module (param above)        
	var AbbspiraFolderNotes = _.extend({}, FolderNotes);
        
	//function that we are going to use to override the original FolderNotes
	//writePermissionEvaluator function
	var writePermissionEvaluator = function(note){
	    return true;
	}
	//first param is the unique name (will show up in the available actions in admin
	//second param is our augmented action module
	//in third param, actionId (or ocActionId or both) is the same as 
	//the one used for the original folder notes
	//fourth param is an object with our overridden writePermissionEvaluator function
	actionModules.registerAction("abbspiraFolderNotes", AbbspiraFolderNotes, {
		"actionId" : "folderNotes",
		//this is new, not required, but specifies to OC which action
		//executer to use. It should match the 'actionId' of the action
		//you are overriding. If not provided, it will use the 
		//"actionId" param above. Both are not needed, but at least one must be provided.
		"ocActionId" : "folderNotes",
		"label" : "Folder Notes",
		"icon" : "envelope",
		"handler" : "modalActionHandler"
	},
	{
		"writePermissionEvaluator" : writePermissionEvaluator
	});

	return AbbspiraFolderNotes;
});
require(["abbspiraFolderNotes"]);

Now, in the admin, you will want to use your overridden action in place of the original. Both ids will show up in the list (above, both 'folderNotes' and 'abbspiraFolderNotes' will be in the list), so you could theoretically use your overridden action in one place and the non-overridden one somewhere else. You can also have two different implementations of the same overridden action. For folder notes, for example, in one trac you may want write access only for the creator, but in another place you may want write access for anyone, but within a certain time constraint.