cancel
Showing results for 
Search instead for 
Did you mean: 

Fiori & CAP: getting custom action working

shf
Explorer
0 Kudos
196

Hi,

In a list report on the detail page (object page) , I'm not understanding in general how custom action bound to an entity is to be implemented. I like to update table Content on an object page with an action related to the current displayed entity which is bound to the object page.

The Fiori sdk docu is confusing, the flexible programming odel homepage with section "custom Actions" is not really helpful, does not explain in comments what should be done.

My main entity is SystemKinds, my table on the object page is SystemKinds.texts . I simply like to add a custom action in the toolbar of table SystemKinds.Texts. Because of having bound the object page to SystemKinds, I assume I have to use "bound action". Once the button is pressed, "title" value should be entered by the user.

I also know that I need side effect once the button on a new action is pressed in order to get values in the SystemKinds.texts updated.

Is there a sample which I can check? In the Fiori Show case app, I cannot find my case.
I need the Fiori annotation for the UI and manifest Setup. I tried different things but nothing works.
I need a short advice in Fiori Setup (annotations with UI) . The action is "setSystemKindsTitles".

Backend Looks like:

 

 

 entity SystemKinds as projection on paltr.BaseSystemKinds
    actions {      
      @(Common.SideEffects: {TargetEntities: ['in/texts']})
      action setSystemKindsTitles(
                                  @(                                   UI.Placeholder:'{i18n>Paltr_Common_InputTitlePlaceHolder}',
                                    title:'{i18n>Paltr_Common_InputTitle}'
                                  )
                                  title : String);


    };

  // --- SystemKinds.texts ---
  @Capabilities: {
    Insertable            : false,
    Deletable             : false,
    Updatable,
    NavigationRestrictions: {Navigability: #None, }
  }
  entity SystemKinds.texts as projection on paltr.BaseSystemKinds.texts;

 

 

In my Service,I have implemented:

 

 

...
class AdminConfigurationService extends cds.ApplicationService {

   const { SystemTypes, SystemKinds } = this.entities;

if (SystemKinds.texts) {
      this.on('setSystemKindsTitles', SystemKinds, async (req) => {
        if (!!SystemKinds.texts?.drafts) {
          await this.update(SystemKinds.texts.drafts, req.data.ID).with({ title: req.data.title });
        }

      });
    }
   ...
}

 

 

My currently used Fiori UI looks like the following:

 

 

using AdminConfigurationService as service from '../../srv/paltr.service.core.adminconfiguration';

annotate service.SystemKinds with @(
    // Listreport SystemKindList

    UI.LineItem                                          : [
        {
            $Type: 'UI.DataField',
            Value: title,
        },
        {
            $Type: 'UI.DataField',
            Value: isPreset,
        },
        {
            $Type: 'UI.DataField',
            Value: isUsable,
        },
    ],

    // SystemKindObjectPage
    UI.HeaderInfo                                        : {
        TypeName      : '{i18n>Paltr_SystemKind}',
        TypeNamePlural: '{i18n>Paltr_SystemKinds}',
        Title         : {
            $Type            : 'UI.DataField',
            Value            : techName,
            ![@UI.Importance]: #High,
            ![@UI.Hidden]    : false,

        },


    },

    // SystemKindObjectPage - section General Information
    UI.FieldGroup #Paltr_GeneralInformationFieldGroup    : {
        $Type: 'UI.FieldGroupType',
        Data : [
            {
                $Type: 'UI.DataField',
                Value: techName,
            },
            {
                $Type: 'UI.DataField',
                Value: ID,
            },
            {
                $Type : 'UI.DataFieldForAnnotation',
                Target: '@UI.ConnectedFields#Paltr_GeneralInformationConnected',
                Label : '{i18n>Paltr_LastChange}',
            },
            {
                $Type: 'UI.DataField',
                Value: isPreset,
            },
        ],
    },
    UI.ConnectedFields #Paltr_GeneralInformationConnected: {
        $Type   : 'UI.ConnectedFieldsType',
        Template: '{modifiedBy}{modifiedAt}',
        Data    : {
            $Type     : 'Core.Dictionary',
            modifiedBy: {
                $Type: 'UI.DataField',
                Value: modifiedBy,
            },
            modifiedAt: {
                $Type: 'UI.DataField',
                Value: modifiedAt,
            },
        },
    },

    // SystemKindObjectPage - section Settings
    UI.FieldGroup #Paltr_SettingsFieldGroup              : {
        $Type: 'UI.FieldGroupType',
        Data : [

        {
            $Type: 'UI.DataField',
            Value: isUsable,
        }],

    },


    UI.Facets                                            : [
        //Section General Information
        {
            $Type : 'UI.ReferenceFacet',
            ID    : 'SystemKind_GeneralInformationFacet',
            Label : '{i18n>Paltr_GeneralInformation}',
            Target: '@UI.FieldGroup#Paltr_GeneralInformationFieldGroup',
        },

        //Section Settings
        {
            $Type : 'UI.CollectionFacet',
            Label : '{i18n>Paltr_BaseData}',
            ID    : 'SystemKind_SettingsFacet',
            Facets: [{
                $Type : 'UI.ReferenceFacet',
                Label : '{i18n>Paltr_Settings}',
                ID    : 'SystemKind_SettingsGroupFacet',
                Target: '@UI.FieldGroup#Paltr_SettingsFieldGroup',
            }],
        },

        // Translations table
        {
            $Type : 'UI.ReferenceFacet',
            Label : '{i18n>Paltr_Translations}',
            ID    : 'Paltr_Translations',
            Target: 'texts/@UI.LineItem#Paltr_Translations',

        },

   
    ],


);

annotate service.SystemKinds.texts with @(UI.LineItem #Paltr_Translations: [
    {
        $Type            : 'UI.DataField',
        Value            : locale,
        Label            : '{i18n>Paltr_Sprache}',
        ![@UI.Importance]: #High,
    },
    {
        $Type            : 'UI.DataField',
        Value            : title,
        ![@UI.Importance]: #High,
    },

    
]);

 

 

The new action shoud appear in the toolbar of "Translations table". I have deleted all my own trials around actions.

Any help would be great. 

Yours

Stephan

 

 

View Entire Topic
sandeep_rs
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi,

Fiori elements OData V4 offers 3 kinds of actions - "bound" which are bound to specific instance, "unbound" which are not related to any instance and "static" - which are bound to the table entity itself and not to the specific selections within. 

In your case, you are looking for a table action that I assume should operate only on the selected rows of the table - if so you need a "bound" action defined at table level. This then needs to have an Action Parameter Dialog configured to allow user to enter the title. The backend could then return the updated instance so that the table is updated with the response.

Please read through the V4 specific sections "Bound and Unbound Actions" and "Action Parameters" in page for more information.

Best Regards,

   Sandeep

shf
Explorer
0 Kudos

hi Sandeep,

thanks for the short explanation. I have already read several times the page you have linked to your answer. This page is describing the situation of having a table and one or many rows are selected before a bound action is working. In this case, the context is delivered to the backend service call related to my action.

In my case, I like to have an action using the annotation-based approach with an input parameter to enter the title and bound to the entity which the complete object page is bound to. The term "bound" means in my case not the table which itself is completely bound to the object page as well. This case is not described in the Fiori docu. 

I was able to setup an unbound action with annotations, the action button will be displayed in the table toolbar. The expected popup dialog is shown if I press the action button and I can enter the title. After confirming the dialog close button, a CREATE request with the CAP action. But the CAP backend service is getting no context (I mean the bound entity) due to the fact that unbound actions never get a context as described in the Fiori docu.

My simple question is: is it possible to get the context (the bound entity) or alternatively, to have an input parameter containing at least the GUID from the underlying bound object page's entity  into the backend call so the CAP backend can use this GUID to select the context itself? Is this possible using the annotations? Or do I have to use the custom extensions in combination with manifest.json and do I have to write the complete dialog popup etc. on my own?

The only answer I know if I like to use the annotation based approach is to use global actions in the object page header. But I like to display the action button on the table toolbar insetad because the action button is for manipulations of all rows of this table and not of the entity which is bound to the complete object page.

 

Yours

Stephan