RAP Feature Control : Contrôler dynamiquement les éléments UI

Catégorie
RAP
Publié
Auteur
Johannes

Le Feature Control permet le contrôle dynamique des éléments UI dans les applications Fiori. Vous pouvez activer, désactiver ou marquer comme obligatoires des champs, actions et opérations en fonction de l’état des données ou des autorisations.

Static vs. Dynamic Feature Control

RAP distingue entre Feature Control statique (déclaratif) et dynamique (programmatique) :

AspectStatic Feature ControlDynamic Feature Control
DéfinitionDans Behavior DefinitionDans Behavior Implementation
ÉvaluationTemps de compilationRuntime
ContexteToujours identiqueDépend de l’instance ou global
Exemplefield ( readonly ) TravelIdfeatures: instance

Static Feature Control

Les features statiques sont déclarées directement dans la Behavior Definition :

define behavior for ZI_Travel alias Travel
persistent table ztravel
lock master
authorization master ( instance )
etag master LastChangedAt
{
create;
update;
delete;
// Features de champ statiques
field ( readonly ) TravelId; " Toujours en lecture seule
field ( mandatory ) CustomerId; " Toujours obligatoire
field ( readonly : update ) AgencyId; " Readonly seulement en update
field ( readonly ) CreatedBy, CreatedAt; " Champs admin
}

Dynamic Feature Control

Les features dynamiques sont calculées au runtime :

define behavior for ZI_Travel alias Travel
{
// Opérations avec Feature Control dynamique
delete ( features: instance );
// Champs avec Feature Control dynamique
field ( features: instance ) Status, Description;
// Actions avec Feature Control dynamique
action ( features: instance ) acceptTravel result [1] $self;
action ( features: instance ) rejectTravel result [1] $self;
// Activer Global Feature Control
static features;
}

Instance Feature Control

Instance Feature Control permet le contrôle des features par instance basé sur l’état de leurs données.

Implémentation

CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_features FOR INSTANCE FEATURES
IMPORTING keys REQUEST requested_features FOR Travel
RESULT result.
ENDCLASS.
CLASS lhc_travel IMPLEMENTATION.
METHOD get_instance_features.
" Lire les données d'instance actuelles
READ ENTITIES OF zi_travel IN LOCAL MODE
ENTITY Travel
FIELDS ( Status )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_travel)
FAILED failed.
" Définir les features par instance
result = VALUE #( FOR ls_travel IN lt_travel
LET lv_is_open = xsdbool( ls_travel-Status = 'O' )
lv_is_accepted = xsdbool( ls_travel-Status = 'A' )
IN (
%tky = ls_travel-%tky
" Delete autorisé seulement avec statut 'Open"
%delete = COND #(
WHEN lv_is_open = abap_true
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled
)
" Champs readonly ou éditables selon le statut
%field-Status = COND #(
WHEN lv_is_open = abap_true
THEN if_abap_behv=>fc-f-unrestricted
ELSE if_abap_behv=>fc-f-read_only
)
%field-Description = COND #(
WHEN lv_is_open = abap_true
THEN if_abap_behv=>fc-f-unrestricted
ELSE if_abap_behv=>fc-f-read_only
)
" Accept-Action seulement avec statut 'Open"
%action-acceptTravel = COND #(
WHEN lv_is_open = abap_true
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled
)
" Reject-Action seulement avec statut 'Accepted"
%action-rejectTravel = COND #(
WHEN lv_is_accepted = abap_true
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled
)
)
).
ENDMETHOD.
ENDCLASS.

Constantes de Feature

ConstanteTypeDescription
if_abap_behv=>fc-o-enabledOperationOpération activée
if_abap_behv=>fc-o-disabledOperationOpération désactivée
if_abap_behv=>fc-f-read_onlyFieldLecture seule
if_abap_behv=>fc-f-mandatoryFieldChamp obligatoire
if_abap_behv=>fc-f-unrestrictedFieldAucune restriction
if_abap_behv=>fc-f-mandatory_and_read_onlyFieldObligatoire et readonly

Global Feature Control

Global Feature Control contrôle les features indépendamment des instances individuelles - typiquement basé sur les autorisations ou états système.

Behavior Definition

define behavior for ZI_Travel alias Travel
{
// Create avec Global Feature Control
create ( features: global );
// Static Actions avec Global Feature Control
static action ( features: global ) massUpdate;
static action ( features: global ) importData;
// Activer Global Features
static features;
}

Implémentation

CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_global_features FOR GLOBAL FEATURES
IMPORTING REQUEST requested_features FOR Travel
RESULT result.
ENDCLASS.
CLASS lhc_travel IMPLEMENTATION.
METHOD get_global_features.
" Vérification des autorisations
AUTHORITY-CHECK OBJECT 'Z_TRAVEL"
ID 'ACTVT' FIELD '01'. " Create
DATA(lv_has_create_auth) = xsdbool( sy-subrc = 0 ).
AUTHORITY-CHECK OBJECT 'Z_TRAVEL"
ID 'ACTVT' FIELD '02'. " Change
DATA(lv_has_change_auth) = xsdbool( sy-subrc = 0 ).
result = VALUE #(
" Create seulement avec autorisation
%create = COND #(
WHEN lv_has_create_auth = abap_true
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled
)
" massUpdate seulement avec autorisation Change
%action-massUpdate = COND #(
WHEN lv_has_change_auth = abap_true
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled
)
).
ENDMETHOD.
ENDCLASS.

Features pour opérations standard

Create, Update, Delete

define behavior for ZI_Travel alias Travel
{
// Static Feature Control
create; " Toujours autorisé
update; " Toujours autorisé
delete ( features: instance ); " Dynamique par instance
}
METHOD get_instance_features.
READ ENTITIES OF zi_travel IN LOCAL MODE
ENTITY Travel
FIELDS ( Status )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_travel).
result = VALUE #( FOR ls_travel IN lt_travel (
%tky = ls_travel-%tky
" Update seulement avec statut Open ou Draft
%update = COND #(
WHEN ls_travel-Status = 'O' OR ls_travel-Status = 'D"
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled
)
" Delete seulement avec statut Open
%delete = COND #(
WHEN ls_travel-Status = 'O"
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled
)
) ).
ENDMETHOD.

Interaction avec Authorization

Feature Control et Authorization se complètent :

  • Authorization : Vérification des autorisations – renvoie une erreur en cas d’accès non autorisé
  • Feature Control : Contrôle UI – empêche les utilisateurs de voir des actions non autorisées
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR Travel
RESULT result.
METHODS get_instance_features FOR INSTANCE FEATURES
IMPORTING keys REQUEST requested_features FOR Travel
RESULT result.
ENDCLASS.
CLASS lhc_travel IMPLEMENTATION.
METHOD get_instance_authorizations.
" Vérification des autorisations
READ ENTITIES OF zi_travel IN LOCAL MODE
ENTITY Travel
FIELDS ( AgencyId )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_travel).
LOOP AT lt_travel INTO DATA(ls_travel).
" Vérifier l'autorisation pour cette agence
AUTHORITY-CHECK OBJECT 'Z_AGENCY"
ID 'AGENCY' FIELD ls_travel-AgencyId
ID 'ACTVT' FIELD '02'.
DATA(lv_authorized) = xsdbool( sy-subrc = 0 ).
APPEND VALUE #(
%tky = ls_travel-%tky
%update = COND #( WHEN lv_authorized = abap_true
THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized )
%delete = COND #( WHEN lv_authorized = abap_true
THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized )
) TO result.
ENDLOOP.
ENDMETHOD.
METHOD get_instance_features.
" Feature Control : Basé sur statut ET autorisation
READ ENTITIES OF zi_travel IN LOCAL MODE
ENTITY Travel
FIELDS ( Status AgencyId )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_travel).
LOOP AT lt_travel INTO DATA(ls_travel).
" Vérifier l'autorisation
AUTHORITY-CHECK OBJECT 'Z_AGENCY"
ID 'AGENCY' FIELD ls_travel-AgencyId
ID 'ACTVT' FIELD '02'.
DATA(lv_has_auth) = xsdbool( sy-subrc = 0 ).
" Combinaison : Statut Open ET autorisation
DATA(lv_can_edit) = xsdbool( ls_travel-Status = 'O' AND lv_has_auth = abap_true ).
APPEND VALUE #(
%tky = ls_travel-%tky
%delete = COND #( WHEN lv_can_edit = abap_true
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled )
%field-Description = COND #( WHEN lv_can_edit = abap_true
THEN if_abap_behv=>fc-f-unrestricted
ELSE if_abap_behv=>fc-f-read_only )
) TO result.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

Définir dynamiquement les champs Mandatory

METHOD get_instance_features.
READ ENTITIES OF zi_travel IN LOCAL MODE
ENTITY Travel
FIELDS ( Status TravelType )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_travel).
result = VALUE #( FOR ls_travel IN lt_travel (
%tky = ls_travel-%tky
" CustomerID est obligatoire pour les voyages d'affaires
%field-CustomerId = COND #(
WHEN ls_travel-TravelType = 'B' " Business
THEN if_abap_behv=>fc-f-mandatory
ELSE if_abap_behv=>fc-f-unrestricted
)
" Approval est obligatoire à partir d'un certain montant
%field-ApproverId = COND #(
WHEN ls_travel-TotalPrice > 5000
THEN if_abap_behv=>fc-f-mandatory
ELSE if_abap_behv=>fc-f-unrestricted
)
) ).
ENDMETHOD.

Optimisation des performances

Feature Control est fréquemment appelé. Optimisez l’implémentation :

METHOD get_instance_features.
" 1. Calculer seulement les features nécessaires
CHECK requested_features-%delete = if_abap_behv=>mk-on
OR requested_features-%action-acceptTravel = if_abap_behv=>mk-on
OR requested_features-%field-Status = if_abap_behv=>mk-on.
" 2. Lire les champs minimaux
READ ENTITIES OF zi_travel IN LOCAL MODE
ENTITY Travel
FIELDS ( Status ) " Seulement ce qui est nécessaire
WITH CORRESPONDING #( keys )
RESULT DATA(lt_travel).
" 3. Boucle efficace
result = VALUE #( FOR ls_travel IN lt_travel (
%tky = ls_travel-%tky
%delete = COND #( WHEN ls_travel-Status = 'O"
THEN if_abap_behv=>fc-o-enabled
ELSE if_abap_behv=>fc-o-disabled )
" ... autres features
) ).
ENDMETHOD.

Bonnes pratiques

  1. Cohérence : Feature Control et Validations doivent être cohérents – un champ désactivé ne devrait pas être vérifié dans une Validation

  2. IN LOCAL MODE : Utilisez IN LOCAL MODE pour éviter les boucles d’Authorization

  3. Accès minimaux à la base de données : Lisez seulement les champs dont vous avez besoin pour la décision de feature

  4. Global vs. Instance : Utilisez Global Feature Control pour les features basées sur les autorisations, Instance pour celles basées sur les données

  5. Vérifier Requested Features : Calculez seulement les features demandées pour optimiser les performances

  6. Documentation : Documentez la logique de feature pour que d’autres développeurs comprennent pourquoi les champs/actions sont disponibles quand

Sujets connexes