Enhancing Activity Guides

This section discusses how to enhance the usage and implementation of activity guides including:

  • Using PeopleCode to enhance activity guides.

  • Creating a custom activity guide data type.

  • Defining activity guide system options.

The activity guide framework provides multiple methodologies for using PeopleCode to implement and customize activity guide usage in your system including:

  • Initializing activity guide instances.

    Whether an activity guide is created dynamically or manually, each instance created from a template can be initialized through a PeopleCode method that you define specifically for this purpose.

  • Performing pre-processing for action items.

    You can define a PeopleCode application class and method to perform pre-processing on an action item before the target transaction is displayed to the user. In addition to performing this pre-processing, the method must also redirect to the target transaction. In addition, Oracle recommends that you develop this application class and method by implementing and extending the PT_RCF:ServiceAGInterface interface class.

    Alternatively, pre-processing can be performed in an iScript that must also specify and transfer the user to the target transaction.

  • Performing post-processing for action items.

    You can define another PeopleCode method to perform post-processing on an action item after the user has completed the task. Post-processing can occur on the local system or the remote system if that’s where the transaction is hosted.

  • Developing custom action buttons.

    The navigation frame provides default navigation buttons to allow a user to move to the next or previous action item. You can create additional navigation buttons—for example, to allow a user to manually mark an action item as complete or to cancel the activity guide instance altogether.

  • Dynamically returning an image URL as context data.

    For fluid activity guides only, you can define a method to use defined context data to dynamically return an image URL as additional context data.

  • Dynamically returning a content URL to be displayed in a modal window.

    For fluid activity guides only, you can define a method to dynamically return a content URL to display additional information. Typically, this additional content is static text; however, it can include context data values.

  • Performing pre-processing for the activity guide pagelet.

    For classic activity guides only, you can define a PeopleCode method to perform pre-processing that will be executed every time the activity guide pagelet is loaded or reloaded in the WorkCenter pagelet area.

Whether an activity guide is created dynamically or manually, each instance created from a template can be initialized through a PeopleCode method that you define specifically for this purpose. This method is identified on the Advanced Options page for the activity guide template.

Limit initialization to operations such as inactivating steps based on the context, initializing the step statuses, updating step assignments, and so on. Also, perform any updates, additions, or deletions that impact translations. Oracle recommends to avoid complex operations such as accessing or updating application tables.

Note: To create your own application class to initialize an activity guide instance, you can clone the PTAI_UTILITIES:InstanceIDCreation class and then modify your copy to suit the needs of your specific activity guide.

In the following example, the PTAI_UTILITIES:InstanceIDCreation class implements and extends the delivered PTAI_ACTION_ITEMS:AGInterface class. The constructor method implements the delivered abstract method by copying the action item assignments from the template and adding the user ID of the current user who instantiates the activity guide.

import PTAI_ACTION_ITEMS:*;
import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_COLLECTION:*;
import PTAI_ACTION_ITEMS:Member:*;


class InstanceIDCreation implements PTAI_ACTION_ITEMS:AGInterface
   method InstanceCreation(&list As PTAI_ACTION_ITEMS:List);
end-class;


/**
* Sets the Instance items status to Assigned and Assigned to Operator ID to %User id.
**/
method InstanceCreation
   /+ &list as PTAI_ACTION_ITEMS:List +/
   /+ Extends/implements PTAI_ACTION_ITEMS:AGInterface.InstanceCreation +/
   
   Local array of string &childItemIds;
   Local integer &i;
   Local boolean &return;
   Local string &ptai_mbr_name, &ptai_mbr_type, &ptai_privset_ID, &ListID, &templateID, &templatelabel, &templatelabel_lng;
   
   Local PTAI_ACTION_ITEMS:ActionItem &item;
   Local PTAI_COLLECTION:Collection &members, &buttons, &contextfields;
   Local PTAI_ACTION_ITEMS:Member &member;
   Local PTAI_ACTION_ITEMS:Privilege &privileges;
   Local PTAI_ACTION_ITEMS:PgltButtons &button;
   
   &list.Status = "IP";
   SQLExec("Select PTAI_PARENT_TMPL From PS_PTAI_LIST Where PTAI_LIST_ID = :1 ", &list.ListId, &templateID);
   
   rem get the template label;
   SQLExec("Select PTAI_LABEL From PS_PTAI_LIST Where PTAI_LIST_ID = :1 ", &templateID, &templatelabel);
   If %Language <> %Language_Base Then
      SQLExec("Select PTAI_LABEL From PS_PTAI_LIST_LNG Where PTAI_LIST_ID =:1 AND LANGUAGE_CD=:2", &templateID, %Language, &templatelabel_lng);
      If All(&templatelabel_lng) Then
         &templatelabel = &templatelabel_lng;
      End-If;
   End-If;
   
   &list.Label = &templatelabel;
   &return = &list.save();
   
   <*
   rem the button label and method;
   &buttons = create PTAI_COLLECTION:Collection();
   
   &button = create PTAI_ACTION_ITEMS:PgltButtons("Cancel", "CancelAG");
   &buttons.InsertItem(&button);
   
   &button = create PTAI_ACTION_ITEMS:PgltButtons("Continue Later", "ExitAG");
   &buttons.InsertItem(&button);
   
   rem &button = create PTAI_ACTION_ITEMS:PgltButtons("Mark Task Completed", "MarkComplete");
   rem &buttons.InsertItem(&button);
   
   &list.SavePgltBtn(&buttons);  
   *>
   
   Rem change the status of the action items;
   &childItemIds = &list.getActionItems();
   
   For &i = 1 To &childItemIds.Len
      &item = create PTAI_ACTION_ITEMS:ActionItem();
      &item.open(&childItemIds [&i]);
      &item.Status = "1";
      /*
         &item.PackageRoot = "W3EB_LIFE_EVENT";
         &item.QualifyPath = ":";
         &item.AppClassID = "ItemStatus";
	*/
      
      Local PTAI_COLLECTION:Collection &oAssignmentColl = create PTAI_COLLECTION:Collection();
      Local PTAI_ACTION_ITEMS:ActionItemAssignments &oAssignment = create PTAI_ACTION_ITEMS:ActionItemAssignments();
      &oAssignment.AssignType = "USER";
      &oAssignment.AssignValue = %OperatorId;
      /* if you want to copy the assignments from template's action items to instance action items, call the getAssignments method and add your new user/role
		 assignments in the returned collection and then call saveAssignments with the combined collection object as shown below. Or if you just want to copy
		 the template assigments to instance and not adding any new assignments, you don't need the following 3 lines of code */
      &oAssignmentColl = &item.getAssignments();
      &oAssignmentColl.InsertItem(&oAssignment As PTAI_COLLECTION:Collectable);
      &item.saveAssignments(&oAssignmentColl);
      
      &return = &item.save();
      
   End-For;
   
   Rem Save the logged in UserID for security and privileges;
   
   &members = create PTAI_COLLECTION:Collection();
   
   &members = &list.getMembers();
   &ptai_mbr_name = %UserId;
   &ptai_mbr_type = "USER";
   
   SQLExec("Select PTAI_PRIVSET_ID From PS_PTAI_PRIVSET Where DESCR = 'Contributor' and PTAI_FEATURE = 'AI' AND ACTIVE_FLAG = 'A' AND PTAI_SYSTEM_ITEM = 'Y' ", &ptai_privset_ID);
   
   
   &member = create PTAI_ACTION_ITEMS:Member(&ptai_mbr_name, &ptai_mbr_type);
   &member.PrivilegeSetID = &ptai_privset_ID;
   &members.InsertItem(&member);
   &list.saveMembers(&members);
   
end-method;

You can define a PeopleCode application class and method to perform pre-processing on an action item before the target transaction is displayed to the user. In addition to performing this pre-processing, the application class and method must redirect to the target transaction. Alternatively, you can implement this functionality in an iScript instead of in an application class.

Important! During pre-processing, do not attempt component buffer access, use think-time functions such as MessageBox, WinMessage, or others, or use system variables.

To implement pre-processing for an action item in an application class and method:

  1. Define an application class that extends the PT_RCF:ServiceAGInterface.

  2. Define the execute method, which implements and extends the execute method in the base class.

  3. Set the %This.StrRedirectUrl property to redirect to the target transaction.

  4. Append the %This.StrAGQueryParameter property to the end of the generated component URL.

  5. Create a related content service definition for this application class.

  6. In the Action Item Details grid, select App Class URL as the link type and select the related content service definition.

The following example shows the PTAI_AGPKG_UNINAV:TestPreProcessing, which implements and extends the PT_RCF:ServiceAGInterface base class:

import PT_RCF:ServiceAGInterface;
import PTAI_ACTION_ITEMS:*;

class TestPreProcessing extends PT_RCF:ServiceAGInterface
   method execute();
end-class;

method execute
   /+ Extends/implements PT_RCF:ServiceInterface.execute +/
   
   Local PTAI_ACTION_ITEMS:ActionItem &ObjAItem;
   Local boolean &boolSaved;
   Local string &market;
   
   &ObjAItem = create PTAI_ACTION_ITEMS:ActionItem();
   &ObjAItem.open(%This.StrActionItemId);
   If &ObjAItem.Status <> "4" Then
      &ObjAItem.Status = "2";
   End-If;
   &boolSaved = &ObjAItem.save();
   
   &market = %Market;
   If None(&market) Then
      &market = "GBL";
   End-If;
   
   %This.StrRedirectUrl = GenerateComponentContentURL(%Portal, %Node, MenuName.PTUN_MENU, &market, Component.PTUN_REMOTENODECFG, Page.PTUN_REMOTENODECFG, "") | %This.StrAGQueryParameter;
end-method;

You can define a PeopleCode application class and method to perform post-processing on an action item after the user has completed the transaction—for example, to update the status of the action item to complete. For post-processing, the method name must be called ItemPostProcess. Post-processing can occur on the local system or the remote system if that’s where the transaction is hosted.

Important! Post-processing can occur on the local system or the remote system if that’s where the transaction is hosted. Post-processing is executed through component save processing only. If you have implemented a custom save button on the page to save the component, the button’s page field properties must be configured to invoke the toolbar save action or the PeopleCode executed by these buttons must include either the DoSave or DoSaveNow built-in functions to trigger the component save events; otherwise, the post-processing specified here will not be executed.

Example 1

In the first example, the class has been developed by implementing and extending the PTAI_ACTION_ITEMS:AGInterface interface class. The ItemPostProcess method defines the post-processing that will occur for this action item.

import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_ACTION_ITEMS:ActionItem;
import PTAI_ACTION_ITEMS:Constants;

class IB_GATEWAY implements PTAI_ACTION_ITEMS:AGInterface
   method IB_GATEWAY();
   rem method InstanceCreation(&list As PTAI_ACTION_ITEMS:List);
   rem method PageletPreProcess(&list As PTAI_ACTION_ITEMS:List);
   rem method ItemPreProcess(&item As PTAI_ACTION_ITEMS:ActionItem);
   method ItemPostProcess(&list_id As string, &item_id As string, &Nodename As string);
end-class;

/* constructor */
method IB_GATEWAY
end-method;

method ItemPostProcess
   /+ &list_id as String, +/
   /+ &item_id as String, +/
   /+ &Nodename as String +/
   /+ Extends/implements PTAI_ACTION_ITEMS:AGInterface.ItemPostProcess +/
   Local PTAI_ACTION_ITEMS:Constants &PTAI_CONSTANTS = create PTAI_ACTION_ITEMS:Constants();
   Local PTAI_ACTION_ITEMS:ActionItem &item = create PTAI_ACTION_ITEMS:ActionItem();
   Local boolean &ret;
   Local string &connurl;
   Local string &defaulturl = "http://machinename:port/PSIGW/PeopleSoftListeningConnector";
   Local number &count;
   
   /*** Debug Test ***/
   rem MessageBox(0, "", 0, 0, "I'm being triggered");
   
   &item.open(&item_id);
   /*** Add logic to check for step completion ***/
   SQLExec("select connurl from psgateway where local_flag='Y'", &connurl);
   SQLExec("select count(*) from psconn", &count);
   
   If All(&connurl) And
         (&connurl <> &defaulturl) And
         &count > 0 Then
      &item.Status = &PTAI_CONSTANTS.STATUS_COMPLETED;
   Else
      &item.Status = &PTAI_CONSTANTS.STATUS_IN_PROGRESS;
   End-If;
   
   /*** Save the Action Item State ***/
   &ret = &item.save();
end-method;

Example 2

In this second example, the ItemPostProcess method includes conditional logic that handles execution differently depending on whether the transaction is on the local node or a remote node. If the ItemPostProcess method is executing on the remote node for the remote transaction, then it uses the PTAI_UPDATEITEM service operation to update status on the local node.

import PTAI_ACTION_ITEMS:*;

Declare Function SecuritySyncMessage PeopleCode PTUN_NODECFGDVW.PTUN_BTN FieldFormula;
Declare Function IsLocalNode PeopleCode PSPTCSSRVDEFN.PTCS_SERVICEURLTYP FieldFormula;

method ItemPostProcess
   /+ &list_id as String, +/
   /+ &item_id as String, +/
   /+ &Nodename as String +/
   Local boolean &boolSaved;
   Local PTAI_ACTION_ITEMS:ActionItem &ObjAItem;
   Local PTAI_ACTION_ITEMS:Constants &AIConstants;
   Local string &Status, &Priority;
   Local string &Required;
   Local number &PercCompl, &Seqno;
   
   &AIConstants = create PTAI_ACTION_ITEMS:Constants();
   /* Test values */
   &Status = &AIConstants.STATUS_COMPLETED;
   &Priority = "1";
   &Required = "Y";
   &PercCompl = 100;
   rem &Seqno = 35;
   If Not IsLocalNode(&Nodename) Then
      Local Message &Req_Msg, &Response;
      Local XmlDoc &requestDoc;
      Local number &i1;
      Local XmlNode &currentParamsNode;
      Local array of XmlNode &SuccessNode, &errorNode;
      Local string &ResponseXml;
      Local SOAPDoc &TransformedDoc;
      
      &Req_Msg = CreateMessage(@("Operation." | "PTAI_UPDATEITEM"), %IntBroker_Request);
      &requestDoc = CreateXmlDoc(GetHTMLText(HTML.PTAI_UPDATEITEM_REQ, %UserId, GetHTMLText(HTML.PTAI_UPDATEITEM_REQ_PARAMS, &item_id, &list_id, &Nodename, &Priority, &Status, &Required, &PercCompl, &Seqno)));
      &Req_Msg.SetXmlDoc(&requestDoc);
      
      &Response = SecuritySyncMessage(&Req_Msg, &Nodename, "PTAI_UPDATEITEM");
      If &Response <> Null Then
         &ResponseXml = &Response.GenXMLString();
         &TransformedDoc = CreateSOAPDoc(&ResponseXml);
         &SuccessNode = &TransformedDoc.DocumentElement.GetElementsByTagName("SAVESUCCESS");
         &errorNode = &TransformedDoc.DocumentElement.GetElementsByTagName("ERRORMSG");
         
         If &SuccessNode <> Null And
               &SuccessNode.Len = 1 Then
            rem do nothing;
         End-If;
         If &errorNode <> Null And
               &errorNode.Len = 1 Then
            Error "Error from Application hosting Activity Guide : " | &errorNode [1].NodeValue;
         End-If;
      Else
         Error "No Response from IB";
      End-If;
   Else
      &ObjAItem = create PTAI_ACTION_ITEMS:ActionItem();
      &ObjAItem.open(&item_id);
      &ObjAItem.Status = &Status;
      &ObjAItem.Priority = &Priority;
      If &Required = "Y" Then
         &ObjAItem.Required = True;
      Else
         &ObjAItem.Required = False;
      End-If;
      &ObjAItem.PercCompl = &PercCompl;
      If All(&Seqno) Then
         &ObjAItem.Sequence = &Seqno;
      End-If;
      &boolSaved = &ObjAItem.save();
   End-If;
end-method;

The activity guide subbanner in fluid activity guides or the navigation frame of the classic WorkCenter provide default navigation buttons to allow a user to move to the next or previous action item. You can create additional navigation buttons to be displayed in these same locations—for example, to allow a user to manually mark an action item as complete or to cancel the activity guide instance altogether. custom action buttons are defined on the Pagelet Options page for a template or instance. Additionally, custom action buttons can be defined per action item on the Configure Related Data page—for example, to add a Submit button to the final step of a sequential activity guide.

Note: For classic activity guides, Oracle recommends that you add no more than two additional custom action buttons.

Important! In custom action buttons, do not attempt component buffer access, use think-time functions such as MessageBox, WinMessage, or others, or use system variables.

Reserved Method Names

Certain reserved method names are recognized for use with guided activity guides. For some reserved method names (for example, MarkComplete and SubmitAGProcess), you must implement custom PeopleCode to perform the designated operation. In other cases (for example, PTAI_NAV_SAVE and PTAI_NAV_AUTO_SAVE), specifying the reserved method name will invoke delivered functions subject to the implementation requirements.

Method Name

Function

How to Implement

ExitAGProcess

Use this method to render a custom Exit button to run PeopleCode (for example, to display a warning message) prior to exiting the activity guide.

Implement the ExitAGProcess method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

MarkComplete

Use this method to render a custom Mark Complete button to allow a user to manually mark an action item as complete.

Implement the MarkComplete method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

ReturnToQuestionnaire

Use this method to render a custom Return to Questionnaire button to delete the current activity guide instance and return the user to the questionnaire page using the default answers defined in the template properties.

Implement the ReturnToQuestionnaire method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

SubmitAGProcess

Use this method to render a custom Submit button that must be placed on the final step of sequential activity guides. When a user clicks this Submit button, two operations occur in this order:

  1. Data added and modified by the user is submitted and then committed to the database.

  2. Your custom SubmitAGProcess program is executed. This method must set the activity guide instance status to complete and then save the instance.

Implement the SubmitAGProcess method as custom PeopleCode. See PTAI_UTILITIES:Utilities for an example.

PTAI_NAV_AUTO_SAVE

Use this method to introduce auto-save functionality for the built-in Next and Previous buttons for non-sequential, guided fluid activity guides.

Note: Auto-save is enabled for sequential and single unit of work activity guides automatically.

No additional implementation is required.

PTAI_NAV_SAVE

For classic activity guides only, use this method to render a custom Save button to invoke the transaction page’s Save button to save the current action item.

  1. At the template level, define PTAI_NAV_SAVE as a configurable field on the Template Properties: Advanced Options page.

  2. For each action item that requires this save functionality, you must map the HTML field ID of the Save button on the page to the configurable field.

    Use your browser’s built-in web developer tools to determine the HTML field ID. For pages that display the standard PeopleTools Save button, the HTML field ID is #ICSave.

    Then, specify this field ID as the value of the PTAI_NAV_SAVE configurable field on the action item’s Configure Related Data page.

PTAI_NAV_SAVE_NEXT

Use this method to combine the save action into the Next button, which invokes the transaction page’s Save button to save the current action item and then display the next action item.

Note: Use this method in classic activity guides only.

  1. At the template level, define PTAI_NAV_SAVE_NEXT as a configurable field on the Template Properties: Advanced Options page.

  2. For each action item that requires this save functionality, you must map the HTML field ID of the Save button on the page to the configurable field.

    Use your browser’s built-in web developer tools to determine the HTML field ID. For pages that display the standard PeopleTools Save button, the HTML field ID is #ICSave.

    Then, specify this field ID as the value of the PTAI_NAV_SAVE_NEXT configurable field on the action item’s Configure Related Data page.

PTAI_NAV_SAVE_PREV

Use this method to combine the save action into the Previous button, which invokes the transaction page’s Save button to save the current action item and then display the previous action item.

Note: Use this method in classic activity guides only.

  1. At the template level, define PTAI_NAV_SAVE_PREV as a configurable field on the Template Properties: Advanced Options page.

  2. For each action item that requires this save functionality, you must map the HTML field ID of the Save button on the page to the configurable field.

    Use your browser’s built-in web developer tools to determine the HTML field ID. For pages that display the standard PeopleTools Save button, the HTML field ID is #ICSave.

    Then, specify this field ID as the value of the PTAI_NAV_SAVE_PREV configurable field on the action item’s Configure Related Data page.

PTAI_GRANT

Use this method to render a custom button that allows a user to grant contributor access to the current step to other users and roles who have contributor access to the instance. Once access has been granted in this manner, only an instance administrator can revoke the grant using the Manage Activity Guide Instances page.

Note: Use this method in fluid activity guides only.

Note: Do not configure the grant action for activity guides that do not support multiple users such as single unit of work and restartable activity guides. Also, the grant action does not make sense for self-service processes when all of the steps in the process are to be performed only by the one user.

Other than specifying the label for the button, no additional implementation is required.

Important! In the current release, if an application package and class has not been specified for another custom button, you must specify a placeholder application package and class in order to be able to save the configuration. However, you do not need to implement the PTAI_GRANT method in this class. Therefore, you can use PTAI_UTILITIES:Utilities as a placeholder.

PTAI_NOTIFY

Use this method to render a custom button that allows a user with contributor access to the instance to send ad hoc notifications to other users by user ID, role, or email address.

Note: Use this method in fluid activity guides only.

Other than specifying the label for the button, no additional implementation is required.

Important! In the current release, if an application package and class has not been specified for another custom button, you must specify a placeholder application package and class in order to be able to save the configuration. However, you do not need to implement the PTAI_NOTIFY method in this class. Therefore, you can use PTAI_UTILITIES:Utilities as a placeholder.

PTAI_OVERVIEW

Use this method to render a custom button that allows a user to view an overview of the activity guide steps along with their status.

Note: Use this method in fluid activity guides only.

Other than specifying the label for the button, no additional implementation is required.

Note: In the current release, if an application package and class has not been specified for another custom button, you must specify a placeholder application package and class in order to be able to save the configuration. However, you do not need to implement the PTAI_OVERVIEW method in this class. Because PTAI_UTILITIES:Utilities has a sample implementation, do not use it as a placeholder.

Moreover, steps can be hidden from display in the process overview depending on business logic. See PTAI_UTILITIES:Utilities for an example how to do this.

Custom Exit Button

In the following example for a classic activity guide, the Exit button that invokes this custom method exits the activity guide and the WorkCenter and returns the user to his or her default homepage.

Note: Exit is not a reserved method name and is different from ExitAGProcess, which is a reserved name.

Declare Function getHomepageURLForPortal PeopleCode FUNCLIB_PTBR.FUNCLIB FieldFormula;

method Exit
   /+ &list_id as String +/
   /+ Returns String +/
   
   Return getHomepageURLForPortal(%Portal);
   
end-method;

For fluid activity guides only, you can define a method to use defined context data to dynamically return an image URL as additional context data.

In the following example, the EMPLID is defined as context data, which is used to dynamically generate the image URL to the employee’s photo:

import PTAI_ACTION_ITEMS:*;
import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_COLLECTION:Collection:*;
...

class AG implements PTAI_ACTION_ITEMS:AGInterface
   method getEmployePhoto(&oCtxt As PTAI_COLLECTION:Collection) Returns string;
   ...

end-class;


method getEmployePhoto
   /+ &oCtxt as PTAI_COLLECTION:Collection +/
   /+ Returns String +/
   Local integer &i = 1;
   While &i <= &oCtxt.Count
      If ((&oCtxt.Item(&i) As PTAI_ACTION_ITEMS:ContextData).fieldname = "EMPLID") Then
         Local Rowset &rs = CreateRowset(Record.EMPL_PHOTO);
         Local string &strEmplID = (&oCtxt.Item(&i) As PTAI_ACTION_ITEMS:ContextData).keyValue;
         &rs.Fill("where EMPLID =:1", &strEmplID);
         Return %Response.GetImageURL(&rs.GetRow(1).GetRecord(Record.EMPL_PHOTO));
      End-If;
      &i = &i + 1;
   End-While;
end-method;

For fluid activity guides only, you can define a method to dynamically return a content URL to display additional information. Typically, this additional content is static text; however, it can include context data values.

Follow these guidelines:

  • The content URL must point to a local, fluid component. Moreover, this component should contain one main fluid page only, with no footer, header, search, or side pages defined in the component.

    Therefore, the content URL cannot point to a classic component, a remote fluid component, or external, non-PeopleSoft content.

  • The page can contain read-only content only. It cannot have any editable fields, links, buttons and other controls that will initiate a server trip or take the user out of activity guide context.

  • Set permissions on the component content to be displayed to allow access by all activity guide contributors.

Implement an application class similar to the following. Invoke the GenerateComponentContentURL built-in function to return the URL to the component.

Note: The following code represents a simple implementation. Use the &oCtxt collection to obtain any of the context data values at runtime to include those values within the additional information displayed.

import PTAI_COLLECTION:Collection:*;

class My_Class
   method getContextURL(&oCtxt As PTAI_COLLECTION:Collection) Returns string;
end-class;

method getContextURL
   /+ &oCtxt as PTAI_COLLECTION:Collection +/
   /+ Returns String +/
   Return GenerateComponentContentURL(%Portal, %Node, MenuName.MY_MENU, "GBL", Component.MY_CONTENT, Page.MY_CONTENT, "U");
end-method;

For classic activity guides, you can define a pagelet pre-processing method that will be executed every time an activity pagelet is loaded or reloaded in the WorkCenter pagelet area. This method must be named PageletPreProcess. The application class containing this method is identified on the Pagelet Options page.

In the following example for the Unified Navigation pagelet, each time the pagelet is reloaded, the PageletPreProcess method creates a link for Manage Related Content for each remote system configured under unified navigation.

import PTAI_ACTION_ITEMS:ActionItem;
import PTAI_ACTION_ITEMS:List;
import PTAI_ACTION_ITEMS:AGInterface;
import PTAI_ACTION_ITEMS:Constants;

class UninavPageletPreprocessor implements PTAI_ACTION_ITEMS:AGInterface
   method PageletPreProcess(&oList As PTAI_ACTION_ITEMS:List);
end-class;


<*  
 method PageletPreprocess() - This method will be called everytime UniNav pagelet is rendered. This function creates a new action item in the UniNav pagelet 
for all the remote RC services. If an earlier created remote service is deleted then the corresponding action item also will be deleted.
*>
method PageletPreProcess
   /+ &oList as PTAI_ACTION_ITEMS:List +/
   /+ Extends/implements PTAI_ACTION_ITEMS:AGInterface.PageletPreProcess +/
   
   Local SQL &sqlGetRemoteSvc;
   Local string &svcId, &svcName, &svcDescr, &svcParamname;
   Local boolean &boolStatus;
   Local integer &seq, &i;
   Local array of string &arrChildItems;;
   Local PTAI_ACTION_ITEMS:ActionItem &oItem = CreateObject("PTAI_ACTION_ITEMS:ActionItem");
   Local PTAI_ACTION_ITEMS:ActionItem &oNewItem = CreateObject("PTAI_ACTION_ITEMS:ActionItem");
   Local PTAI_ACTION_ITEMS:Constants &PTAI_CONSTANTS = CreateObject("PTAI_ACTION_ITEMS:Constants");
   
   <* Every time the pagelet is opened child items under the node 'Related Content Setup' will be deleted and recreated. Nodes are deleted and added again
      everytime because, if some remote services are deleted then it will get reflected in the tree immediately and to prevent the addition of duplicate nodes *>
   try
      &oItem.open("PAPP_UNITM8_PAPP_UNINA1003");
      &arrChildItems = &oItem.getChildActions();
      If All(&arrChildItems) Then
         For &i = 1 To &arrChildItems.Len
            &oItem.open(&arrChildItems [&i]);
            If Not &oItem.ItemId = "PAPP_UNITM9_PAPP_UNINA1003" Then
               try
                  &boolStatus = &oItem.delete();
               catch Exception &e1
               end-try;
            End-If;
         End-For;
      End-If;
      
      SQLExec("Select MAX(PTAI_SEQ) from PS_PTAI_ITEM where PTAI_LIST_ID = :1", &oList.ListId, &seq);
      &sqlGetRemoteSvc = GetSQL(SQL.EPPAI_GET_REMOTE_SVC);
      While &sqlGetRemoteSvc.Fetch(&svcId, &svcName, &svcDescr)
         &oNewItem.new(&svcId, &svcName, &oList.ListId);
         &oNewItem.DescrLong = &svcDescr;
         &oNewItem.ServiceId = &svcId;
         &oNewItem.ParentId = "PAPP_UNITM8_PAPP_UNINA1003";
         &oNewItem.Status = "1";
         &oNewItem.CreatedDateTime = %Datetime;
         &oNewItem.CreatedByOprid = %UserId;
         &oNewItem.LastUpdatedDateTime = %Datetime;
         &oNewItem.LastUpdatedByOprid = %UserId;
         &oNewItem.Target = "T";
         &oNewItem.Type = "C";
         Local PTAI_COLLECTION:Collection &oAssignmentColl = create PTAI_COLLECTION:Collection();
         Local PTAI_ACTION_ITEMS:ActionItemAssignments &oAssignment = create PTAI_ACTION_ITEMS:ActionItemAssignments();
         &oAssignment.AssignType = &PTAI_CONSTANTS.MEMBER_TYPE_ROLE;
         &oAssignment.AssignValue = "Portal Administrator";
         
         &oAssignmentColl = &oNewItem.getAssignments();
         &oAssignmentColl.InsertItem(&oAssignment As PTAI_COLLECTION:Collectable);
         &oNewItem.saveAssignments(&oAssignmentColl);
         &seq = &seq + 10;
         &oNewItem.Sequence = &seq;
         &boolStatus = &oNewItem.save();
      End-While;
      &sqlGetRemoteSvc.Close();
   catch Exception &e
   end-try;
end-method;

Use the Define Activity Guide Data Type page to define custom activity guide data types.

Navigation:

PeopleTools > Activity Guides > Activity Guide Data Types

This example illustrates the fields and controls on the Define Activity Guide Data Type page. You can find definitions for the fields and controls later on this page.

Define Activity Guide Data Type page

Field or Control

Description

Data Type

Displays the identifier entered for the custom data type on the Add a New Value page.

Label

Enter the descriptive name for the custom data type.

Long Description

Enter a description for the custom data type.

Object Owner ID

Select the object owner ID.

Package

Enter the name of the application package that contains your custom application class.

Path

Enter the names of each subpackage in the application class hierarchy that define the location of the application class. Separate subpackage names by a colon. If the class is defined in the top-level application package, enter or select the colon.

Class ID

Enter the name of the application class that extends PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource base class.

To implement a custom activity guide data type, create a PeopleCode application class definition:

  1. Extend the PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource base class. For example:

    import PTPP_PORTAL:UTILITY:Collection;
    import PTPP_COLLECTIONS:*;
    
    import PTGP_GUIDED_PROCESS:DataSources:*;
    import PTGP_GUIDED_PROCESS:GuidedProcesses:*;
    import PTGP_GUIDED_PROCESS:Elements:*;
    import PTGP_GUIDED_PROCESS:Buttons:*;
    import PTGP_GUIDED_PROCESS:Steps:*;
    
    class MyCustAGDataType extends PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource
  2. In the constructor method for your custom application class, set default values for only the properties necessary to differentiate it from the BaseDataSource class. For example:

    method MyCustAGDataType
       /+ &pId as String +/
       
       %Super = create PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource(&pId);
       %This.setDataSourceType("MyCustAGDataType");
       %This.RenderType = %This.RENDER_TYPE_NONGUIDED_OPTIMIZED;
       
       /* Do not need to defer loading */
       %This.DeferMainGroupletsLoading = False;
       
    end-method;
    
  3. Do not implement and thereby override the populateDataSourceObject method of PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.

    The populateDataSourceObject method loads critical activity guide template metadata.

  4. Implement the initializeContainerComponent method manipulate the look of the container component using style sheets, JavaScript, or data source properties. For example:

    method initializeContainerComponent
       /+ Extends/implements PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.initializeContainerComponent +/
       
       Local string &renderType, &scname;
       
       /* Call the super */
       %Super.initializeContainerComponent();
       
       /* Get the collection name */
       &scname = %Request.GetParameter(&cstQUERYPARAMETER_SCNAME);
       If (All(&scname)) Then
          %This.CollName = &scname;
       End-If;
       
       /* Override render type */
       &PTGP_NAVCOLL_RENDER_TYPE = "";
       &renderType = %Request.GetParameter(&cstQUERYPARAMETER_RENDERTYPE);
       If (All(&renderType)) Then
          try
             %This.RenderType = &renderType;
             &PTGP_NAVCOLL_RENDER_TYPE = &renderType;
          catch Exception &e
          end-try;
       End-If;
       
       /* Override panel type */
       %This.ShowSide1PanelCollapsible = True;
       %This.ShowSide1PanelOpenWhenCollapsible = ( Not %This.IsSmallFormFactorMode);
       
    end-method;
    
  5. Implement the initializeGroupletComponent method manipulate the look of the grouplet component using style sheets, JavaScript, or data source properties. While it must call the populateGuidedProcessObject to load the process tree, it must not load data source metadata. For example:

    method initializeGroupletComponent
       /+ Extends/implements PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.initializeGroupletComponent +/
       
       Local string &scname;
       
       /* Override render type */
       If (All(&PTGP_NAVCOLL_RENDER_TYPE)) Then
          %This.RenderType = &PTGP_NAVCOLL_RENDER_TYPE;
       End-If;
       
       /* Get the collection name */
       &scname = %Request.GetParameter(&cstQUERYPARAMETER_SCNAME);
       If (All(&scname)) Then
          %This.CollName = &scname;
       End-If;
       
       %Super.initializeGroupletComponent();
       
    end-method;
  6. Implement the populateGuidedProcessObject method to load the process tree from your custom data source. For example:

    method populateGuidedProcessObject
       /+ Returns PTGP_GUIDED_PROCESS:GuidedProcesses:BaseGuidedProcess +/
       /+ Extends/implements PTGP_GUIDED_PROCESS:DataSources:ActivityGuideDataSource.populateGuidedProcessObject +/
       
       Local string &text, &iconUrl, &msgNode;
       Local string &defaultFolderIconUrl, &defaultContentIconUrl;
       Local boolean &succeeded;
       
       Local Record &rec;
       
       Local PTGP_GUIDED_PROCESS:GuidedProcesses:BaseGuidedProcess &thisProcess;
       
       Local PTGP_GUIDED_PROCESS:Elements:StepElement &thisStep;
       Local PTGP_GUIDED_PROCESS:Elements:StepGroupElement &thisStepGroup, &theRootStep;
       Local PTGP_GUIDED_PROCESS:Elements:ContextTextElement &headerText;
       Local PTGP_GUIDED_PROCESS:Elements:ButtonElement &thisButton;
       
       Local PTPP_COLLECTIONS:NavigationCollection &thisNavColl;
       Local PTPP_COLLECTIONS:Folder &thisFolder;
       Local PTPP_COLLECTIONS:Shortcut &thisShortcut;
       
       
       &thisProcess = create PTGP_GUIDED_PROCESS:GuidedProcesses:BaseGuidedProcess("PTGPTester");
       &theRootStep = &thisProcess.RootStep;
       
       
       Evaluate %This.RenderType
       When %This.RENDER_TYPE_HORIZONTAL
       When %This.RENDER_TYPE_VERTICAL_OPTIMIZED_SEQUENTIAL
       When %This.RENDER_TYPE_VERTICAL_NONOPTIMIZED_SEQUENTIAL
          &thisProcess.IsSequential = False;
          Break;
          
       When %This.RENDER_TYPE_VERTICAL_OPTIMIZED
       When %This.RENDER_TYPE_VERTICAL_NONOPTIMIZED
       When %This.RENDER_TYPE_NONGUIDED_OPTIMIZED
       When %This.RENDER_TYPE_NONGUIDED_NONOPTIMIZED
          Break;
          
       End-Evaluate;
       
       
       /* Default icons */
       &defaultFolderIconUrl = %Response.GetImageURL(Image.PTPP_FN_LARGE_FOLDER_ICN);
       &defaultContentIconUrl = %Response.GetImageURL(Image.PTPP_FN_LARGE_CONTENT_ICN);
       
       &rec = CreateRecord(Record.PTPP_SITE_OPT);
       &rec.PORTAL_NAME.Value = %Portal;
       If (&rec.SelectByKey()) Then
          /* Site default */
          &defaultFolderIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGFLDICN.Value);
          &defaultContentIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGCNTICN.Value);
       Else
          SQLExec("SELECT MSGNODENAME FROM PS_PTPP_OPTIONS", &msgNode);
          &rec = CreateRecord(Record.PTPP_OPTIONS);
          &rec.MSGNODENAME.Value = &msgNode;
          If (&rec.SelectByKey()) Then
             /* System default */
             &defaultFolderIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGFLDICN.Value);
             &defaultContentIconUrl = %Response.GetImageURL(&rec.PTPP_SCLGCNTICN.Value);
          End-If;
       End-If;
       
       
       /* Get the Collection */
       try
          &thisNavColl = create PTPP_COLLECTIONS:NavigationCollection(%This.PortalName, %This.CollName);
       catch Exception &ex1
          /* Ignore any error */
       end-try;
       
       
       /* Generate the list */
       If ((&thisNavColl <> Null) And
             &thisNavColl.Authorized And
             &thisNavColl.IsValid) Then
          
          /* Root steps */
          If (&thisNavColl.Shortcuts <> Null) Then
             
             &thisShortcut = &thisNavColl.Shortcuts.First();
             While (&thisShortcut <> Null)
                
                /* Create the step */
                &thisStep = create PTGP_GUIDED_PROCESS:Elements:StepElement(&thisShortcut.Name);
                &thisStep.Label = UnEscapeHTML(&thisShortcut.Label);
                &thisStep.URL = &thisShortcut.AbsoluteContentURL;
                &thisStep.SequenceNumber = &thisShortcut.SequenceNumber;
                &thisStep.IsFluid = &thisShortcut.IsFluid;
                
                If (&thisShortcut.IsNewWindow) Then
                   &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURLnewWin) | "', 1);";
                End-If;
                
                If (&thisShortcut.IsTopWindow) Then
                   &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURL) | "', 4);";
                End-If;
                
                &iconUrl = &thisShortcut.ImageURL;
                If (All(&iconUrl)) Then
                   &thisStep.IconUrl = &iconUrl;
                Else
                   &thisStep.IconUrl = &defaultContentIconUrl;
                End-If;
                
                &theRootStep.addChildStep(&thisStep);
                
                /* Next shortcut */
                &thisShortcut = &thisNavColl.Shortcuts.Next();
                
             End-While;
             
          End-If;
          
          
          /* Root folders */
          If (&thisNavColl.Folders <> Null) Then
             
             &thisFolder = &thisNavColl.Folders.First();
             While (&thisFolder <> Null)
                
                /* Create the step group */
                &thisStepGroup = create PTGP_GUIDED_PROCESS:Elements:StepGroupElement(&thisFolder.Name);
                &thisStepGroup.Label = UnEscapeHTML(&thisFolder.Label);
                &thisStepGroup.SequenceNumber = &thisFolder.SequenceNumber;
                
                &iconUrl = &thisFolder.ImageURL;
                If (All(&iconUrl)) Then
                   &thisStepGroup.IconUrl = &iconUrl;
                Else
                   &thisStepGroup.IconUrl = &defaultFolderIconUrl;
                End-If;
                
                /* First level child steps */
                If (&thisFolder.Shortcuts <> Null) Then
                   
                   &thisShortcut = &thisFolder.Shortcuts.First();
                   While (&thisShortcut <> Null)
                      
                      /* Create the step */
                      &thisStep = create PTGP_GUIDED_PROCESS:Elements:StepElement(&thisShortcut.Name);
                      &thisStep.Label = UnEscapeHTML(&thisShortcut.Label);
                      &thisStep.URL = &thisShortcut.AbsoluteContentURL;
                      &thisStep.SequenceNumber = &thisShortcut.SequenceNumber;
                      &thisStep.IsFluid = &thisShortcut.IsFluid;
                      &thisStepGroup.addChildStep(&thisStep);
                      
                      If (&thisShortcut.IsNewWindow) Then
                         &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURLnewWin) | "', 1);";
                      End-If;
                      
                      If (&thisShortcut.IsTopWindow) Then
                         &thisStep.OnClick = "LaunchURL(null, '" | EscapeJavascriptString(&thisShortcut.AbsolutePortalURL) | "', 4);";
                      End-If;
                      
                      /* Next shortcut */
                      &thisShortcut = &thisFolder.Shortcuts.Next();
                      
                   End-While;
                   
                End-If;
                
                /* Sort and add the step group when it's not empty */
                If (&thisStepGroup.ChildSteps.Count > 0) Then
                   &succeeded = &thisStepGroup.ChildSteps.sort(&cstSEQ_NUMBER, True);
                   &theRootStep.addChildStep(&thisStepGroup);
                End-If;
                
                /* Next folder */
                &thisFolder = &thisNavColl.Folders.Next();
                
             End-While;
             
          End-If;
          
          
          /* Sort the root list */
          &succeeded = &theRootStep.ChildSteps.sort(&cstSEQ_NUMBER, True);
          
          
          /* Set the current step id to the first item */
          &thisStep = &theRootStep.ChildSteps.get(1);
          If (All(&thisStep)) Then
             &thisStepGroup = (&thisStep As PTGP_GUIDED_PROCESS:Elements:StepGroupElement);
             If (All(&thisStepGroup)) Then
                &thisProcess.CurrentStepId = &thisStepGroup.ChildSteps.get(1).ID;
             Else
                &thisProcess.CurrentStepId = &thisStep.ID;
             End-If;
          End-If;
          
          
          /* Header texts */
          &headerText = create PTGP_GUIDED_PROCESS:Elements:ContextTextElement("label");
          &headerText.StyleClass = "ps_ag-header-context-title";
          &headerText.Text = &thisNavColl.Label;
          &thisProcess.addHeaderText(&headerText);
          
          &text = &thisNavColl.Description;
          If (All(&text)) Then
             &headerText = create PTGP_GUIDED_PROCESS:Elements:ContextTextElement("description");
             &headerText.StyleClass = "ps_ag-header-context-text";
             &headerText.Text = &text;
             &thisProcess.addHeaderText(&headerText);
          End-If;
          
          
          /* Header buttons */
          &thisButton = create PTGP_GUIDED_PROCESS:Buttons:ExitButton(&thisProcess.ID | "-ExitButton");
          &thisProcess.addHeaderButton(&thisButton);
          
          &thisButton = create PTGP_GUIDED_PROCESS:Buttons:PreviousButton(&thisProcess.ID | "-PreviousButton");
          &thisProcess.addHeaderButton(&thisButton);
          
          &thisButton = create PTGP_GUIDED_PROCESS:Buttons:NextButton(&thisProcess.ID | "-NextButton");
          &thisProcess.addHeaderButton(&thisButton);
          
       End-If;
       
       
       Return &thisProcess;
       
    end-method;

Use the Activity Guide System Options page to define integration with Approval Workflow Engine (AWE).

Navigation:

PeopleTools > Activity Guides > Activity Guide System Options

This example illustrates the fields and controls on the Activity Guide System Options page. You can find definitions for the fields and controls later on this page.

Activity Guide System Options page

Classic Approval Chain

Field or Control

Description

Menu Name

Enter the menu name that contains the classic AWE component—for example, EOAW_APPROVAL_WORKFLOW.

Component Name

Enter the name of the classic AWE component—for example, EOAW_APPCHAIN_VIEW.

Fluid Approval Chain

Field or Control

Description

Fluid Menu

Enter the menu name that contains the fluid AWE component—for example, EOAWMA_MAIN_FL.

Fluid Component

Enter the name of the fluid AWE component—for example, EOAWMA_MAIN_FL.

You may wish to generate analytics or to report on the progress of activity guide instances, steps, statuses, and so on. For example, your analytics could show instances completed, progress within instances from a specific template, and so on. The Activity Guide search definition type enables you to index activity guide instance data in search engine that then can be used for analytics in PeopleSoft Insights. You can also use an application table as an additional data source in order to provide supplemental information in the index. After creating a search definition and indexing it, you can create visualizations.