Apex Class as action

Pat VachonPat Vachon ✭✭
edited June 25 in Ideas
This would be really really cool. The ability to call a class. Specifically for connecting to trigger-ready flows using the start() method in apex. Action Name: Apex Class Lookup function for Apex Class Display inputs required for Class. (most of the time all that would be required would be an Id) This would allow programming to be done almost completely declaretively. Not only that we could set when to run the code. On model save, on button click, etc
Tagged:
3
3 votes

Implemented · Last Updated

Comments

  • Pat VachonPat Vachon ✭✭
    edited June 25
    Also, javascript snippets call apex classes?
  • edited March 2017
    Great idea, we have been considering doing this since Skuid was first created. For this to work, we would have to do either of the following:

    (a) support several of the most common interfaces, such as:
     - Schedulable - execute()
     - Batchable - start()
     - Process.Plugin - invoke()
     - Flow.Interview  - start()

    (b) create our own interface that we would expect others to implement, such as:

    global interface Executable {
        String execute(String params);
    }
  • Pat VachonPat Vachon ✭✭
    edited June 25
    hehehehe ... that mostly went over my head. :D

    So is this possible and/or likely to ever happen?
  • Jack SanfordJack Sanford ✭✭
    edited June 25
    In the Chicago training right now, it looks like this is implemented in Banzai... not sure which way they managed to make it happen. 
  • Pat VachonPat Vachon ✭✭
    edited January 2016
    How about Calling Flow as action. Would be awesome too!
  • edited June 25
    The Banzai release allows you to run Invocable Apex Actions from the Action Framework. Apex can be defined as "invocable" using the @InvocableMethod annotation. 
  • Pat VachonPat Vachon ✭✭
    edited January 2016
    Ok. My first foray into this and I'm surely missing something.

    Can you provide documentation on this method. skuid.sfdc.api.makeRequest

    I think it's what I need to use to send a BLOB through to the class. I tried the Skuid action "Run an Apex Action" and get the following error.

    image

    Here's the test page. The class is what you'd expect. ;)
    <skuidpage unsavedchangeswarning="yes" personalizationmode="server" showsidebar="true" showheader="true">    <models>       <model id="Contact" limit="1" query="true" createrowifnonefound="false" adapter="" type="" sobject="Contact">          <fields>             <field id="Id"/>          </fields>          <conditions/>          <actions/>       </model>    </models>    <components>       <pagetitle model="Contact" uniqueid="sk-1NII09-102">          <maintitle>             <template>{{Name}}</template>          </maintitle>          <subtitle>             <template>{{Model.label}}</template>          </subtitle>          <actions>             <action type="multi" label="Attach File">                <actions>                   <action type="sfdc-custom-apex" sfdcactionname="UploadFileClass">                      <inputs xmlns="http://www.w3.org/1999/xhtml">                      </inputs>                   </action>                </actions>             </action>          </actions>       </pagetitle>    </components>    <resources>       <labels/>       <javascript/>       <css/>    </resources>    <styles>       <styleitem type="background" bgtype="none"/>    </styles> </skuidpage>

  • Jack SanfordJack Sanford ✭✭
    edited May 2016
    I'm not used to looking at the XML for this, and even so I could be totally wrong here, but it looks like Apex would have trouble reading your input as a List (InvocableMethod needs to receive a list and return a list). I've had trouble working in run Apex action because of that limitation and end up just using sforce.apex.execute an reworking my InvocableMethod as a webservice.

    Some clear examples of what would go in that input field would be super helpful!

    J. gave me one example here but I had already switched to webservice and haven't tried it yet...
  • Pat VachonPat Vachon ✭✭
    edited January 2016
    Ok. Each input as their own list or all inputs in one list. I'd assume the former. If so, I can't see how a single input value would look different than a single input list with a single value.

    First need to be be able to set the input value for a BLOB. I was hoping for a popup to be automatically generated, but that was wishful thinking. :P
  • Emily DavisEmily Davis ✭✭
    edited January 2017
    I'm not sure if this is helpful, but I think you should still be able to call an invocable method and pass in single arguments, rather than lists. The syntax is not exactly what you would expect. Here's an example of an invocable method that runs an approval process action on a record (in my case, a Case record), and can be called from Skuid.
    global class CaseApprovalActions {
        
        @InvocableMethod(label='Approve Record')
        global static List<ApproveResponse> approveRecord(List<ApproveRequest> requests) {
            List<ApproveResponse> responses = new List<ApproveResponse>();
            ApproveResponse res = new ApproveResponse();
            responses.add(res);
            
            ApproveRequest req = requests[0];
            
            ProcessInstanceWorkItem item = [SELECT Id FROM ProcessInstanceWorkItem WHERE Id = :req.workItemId LIMIT 1];
            
            if (item.Id != null && (req.actionType == 'approve' || req.actionType == 'reject')) {
                Approval.ProcessWorkItemRequest pwr = new Approval.ProcessWorkItemRequest();
                pwr.setWorkItemId(item.Id);
                
                if (req.actionType == 'approve') { pwr.setAction('Approve'); }
                else if (req.actionType == 'reject') {pwr.setAction('Reject'); }
                
                pwr.setComments(req.comments);
                
                Approval.process(pwr);
            }
            
            return responses;
        }
        
        global class ApproveRequest {
            @InvocableVariable(required=truedescription='The pending Work Item Id to approve/reject' label='Work Item Id')
            public Id workItemId;
            
            @InvocableVariable(required=truedescription='Comments on why the user is approving/rejecting the record' label='Comments')
            public String comments;
            
            @InvocableVariable(required=truedescription='Options are "approve", "reject"' label='Action Type')
            public String actionType;
        }
        
        global class ApproveResponse {
            @InvocableVariable
            public String message;
        }
        
    }
    You just need to set up a class (e.g. ApproveRequest) for the List type to pass into the method, and then for every @InvocableVariable defined in the class, you can pass in a value from Skuid.

    Skuid button configuration:
    image


Sign In or Register to comment.