
ADT - Metadata Wizard [MIA]
In diesem Artikel schauen wir uns den Metadata Wizard an und wie er vielleicht in Zukunft dein Leben bei der Anlage von UI-Annotationen in RAP vereinfachen könnte.
Inhaltsverzeichnis
In diesem Artikel gehen wir durch das Konzept des "Metadata Wizard", wie er aktuell funktioniert und wie er dir in Zukunft vielleicht helfen kann.
Einleitung
Im letzten Artikel hatten wir ein RAP Objekt per Template erstellt und damit viel Zeit bei der Anlage der Objekte gespart. Allerdings waren wir noch nicht ganz zufrieden mit dem UI, da noch zu viele Informationen angezeigt werden und es keine Struktur gibt. In diesem Artikel überarbeiten wir die Metadata Extension, aber nicht per Hand, sondern wir verwenden den Prototypen eines Wizards den wir als IDE Action implementiert haben.
Idee
In der Metadata Extension definieren wir unsere UI-Annotationen, um das Fiori Elements UI zu erstellen, die Elemente zu definieren und zu positionieren. Dabei folgen wir in den meisten Fällen erst einmal dem gleichen Pattern, um den List Report und die folgende Object Page zu gestalten. Die Generatoren definieren dabei meist eine erste Ansicht, die wir aber eigentlich immer überarbeiten müssen. Hier kommt der Metadata Wizard zum Einsatz, der uns einen Schnellstart in die Überarbeitung gibt und auf einfache Weise erlaubt die Elemente zu platzieren, auszublenden und zu gruppieren.
IDE Action
In diesem Abschnitt schauen wir etwas auf den Bau der IDE Action, welche Ideen wir verfolgt haben und wie das Ergebnis am Ende aussieht.
Information
Welche Informationen benötigen wir eigentlich, wenn wir die Annotationen für die Felder erstellen? In den meisten Fällen fangen wir erst einmal mit den verschiedenen Fassaden an und ordnen diesen dann die Felder zu. Starten wir als mit einer Eingabe für unsere IDE Action. Im einfachsten Fall haben wir einen Bereich für die verschiedenen Facets und einen Bereich für die Felder. Da wir hier verschiedene Informationen pflegen wollen, legen wir uns zwei Tabellen an. Wie du eine IDE Action erstellst und designst, findest du über die Suche zu den IDE Actions.
TYPES:
BEGIN OF facet,
"! <p class="shorttext">ID</p>
id TYPE string,
"! <p class="shorttext">Parent ID</p>
parent_id TYPE string,
"! <p class="shorttext">Label</p>
label TYPE string,
"! <p class="shorttext">Type</p>
type TYPE facet_type,
"! <p class="shorttext">Position</p>
position TYPE string,
"! <p class="shorttext">Qualifier</p>
target_qualifier TYPE string,
"! <p class="shorttext">Reference</p>
target_element TYPE string,
"! <p class="shorttext">Field to Hide</p>
hide_facet TYPE string,
old TYPE string,
END OF facet.
TYPES facets TYPE STANDARD TABLE OF facet WITH EMPTY KEY.
TYPES:
BEGIN OF field,
"! <p class="shorttext">Field</p>
name TYPE string,
"! <p class="shorttext">New Label</p>
label TYPE string,
"! <p class="shorttext">Selection [P]</p>
pos_selection TYPE string,
"! <p class="shorttext">LineItem [P]</p>
pos_lineitem TYPE string,
"! <p class="shorttext">Identification [P]</p>
pos_identification TYPE string,
"! <p class="shorttext">FieldGroup [P]</p>
pos_fieldgroup TYPE string,
"! <p class="shorttext">Qualifier</p>
qualifier TYPE string,
"! <p class="shorttext">Field to Hide</p>
hide_field TYPE string,
END OF field.
TYPES fields TYPE STANDARD TABLE OF field WITH EMPTY KEY.
Da wir nun die ersten Strukturen definiert haben, wirst du bereits aus den Feldern erkennen, welche Features wir unterstützen. So können wir Felder und Bereiche über Felder ausblenden, verschiedene Bereiche erstellen oder eigene Label vergeben. Starten wir die IDE Action, dann finden wir bereits alle Elemente auf der Eingabe.
Über den "Hide" Button, wollen später komplett vom UI verschwinden lassen, wenn es sich zum Beispiel um UUID Schlüsselfelder handelt und ohne viel Logik zu implementieren.
Defaults
Im nächsten Schritt wollen wir die Defaultwerte vorbefüllen. Beginnen wir daher mit den verschiedenen Facets im View. Über die XCO Bibliothek prüfen wir, ob es den Core Data Service im System gibt, dabei verwenden wir den Namen der Metadata Extension, der vom Namen des Core Data Service abweichen könnte. Dann benötigen wir eigentlich immer eine allgemeine Facet, der wir alle Felder zuordnen, ähnlich wie der Standard der Generatoren. Als Nächstes erzeugen wir pro Composition im Core Data Service eine Facet, um die Entitäten als Tabelle einzubinden. Die Felder können wir direkt der allgemeinen Facet zuweisen und zählen die Position einfach nur noch in 10er Schritten nach oben. Da Ergebnis können wir dann an die IDE Action als Default übergeben.
Führen wir nun noch einmal die IDE Action aus, dann erhalten wir die entsprechende Vorbefüllung. In diesem Fall verwenden wir die Metadata Extension der Entität ZBS_C_SASale von unserer Sales App.
Anpassung
Die IDE Actions sollen aber nicht nur "dumme" Masken sein, die du am Ende befüllen kannst, sondern dich auch bei der Arbeit unterstützen. Zum Beispiel wenn du den Qualifier der Facet änderst, dann sollten alle Felder mit der Facet sich ebenfalls ändern, da wir sonst keine Zuordnung mehr haben oder im schlimmsten Fall wir selbst die Anpassung für jedes Feld vornehmen müssen.
Wollen wir Felder auf dem UI ausblenden, dann verwenden wir eine Aktion in der Tabelle. Hier müssen wir nur noch das Feld wählen und die Aktion ausführen, dann werden die Eigenschaften gelöscht und das Feld später auf "hidden" gesetzt.
Features
Im Moment unterstützt dich die IDE Action vor allem bei der Anlage der UI-Annotationen. dabei fehlen immer noch komplexere Features wie die Header, Buttons und andere Annotationen. Daher ist die Aktion für einen schnellen Einstieg gedacht und die weiteren Anpassungen müssen durch dich als Entwickler erfolgen. Ein offener Punkt ist die Analyse der bestehenden UI-Annotationen, sodass der Wizard auch für Anpassungen verwendet werden könnte. Wir würden den Quellcode laden und die Maske vorbefüllen. Dies würde aber auch beinhalten, dass mehr Features unterstützt werden.
Generierung
Nachdem der Prototype der IDE Action nun fertig ist, kümmern wir uns um die Metadaten unserer Sales App aus dem letzten Artikel und aktualisieren das UI mit unserer neuen Aktion.
Sales
Die Metadata Extension ZBS_C_SASale enthält den List Report, die eigentliche Object Page und einige Entitäten unterhalb. Deshalb sollte die Object Page etwas aufgeräumter sein. Im ersten Schritt gehen wir daher in die Metadata Extension und löschen alle bisherigen Informationen außer den Header Annotationen. Mit STRG + ALT + R starten wir dann die Action und können mit der Konfiguration starten.
Nach der Ausführung der Action erhalten wir noch den Code Vergleich und können die generierten Änderungen prüfen. In diesem Fall übernehmen wir das Ergebnis.
Schauen wir uns die UI-Annotationen an, dann wurden die verschiedenen Facets generiert und die Felder mit den entsprechenden Abgrenzungen übernommen. Im Beispiel findest du das generierte Coding aus der Konfiguration.
@Metadata.layer: #CORE
@UI.headerInfo.title.type: #STANDARD
@UI.headerInfo.title.value: 'PartnerNumber'
@UI.headerInfo.description.type: #STANDARD
@UI.headerInfo.description.value: 'SalesDate'
annotate view ZBS_C_SASALE with
{
@UI.facet: [
{
id: 'idGeneral',
label: 'General Information',
position: 10 ,
type: #IDENTIFICATION_REFERENCE,
targetQualifier: 'GENERAL'
},
{
id: 'idDifference',
label: 'Difference',
position: 20,
type: #IDENTIFICATION_REFERENCE,
targetQualifier: 'DIFF'
},
{
id: 'idInformation',
label: 'Information',
position: 30,
type: #IDENTIFICATION_REFERENCE,
targetQualifier: 'INFO'
},
{
id: 'idAdmin',
label: 'Admin Fields',
position: 40,
type: #IDENTIFICATION_REFERENCE,
targetQualifier: 'ADMIN'
},
{
id: 'idSASeller',
label: 'Seller',
position: 50,
type: #LINEITEM_REFERENCE,
targetElement: '_SASeller'
},
{
id: 'idSASold',
label: 'Sold',
position: 60,
type: #LINEITEM_REFERENCE,
targetElement: '_SASold'
},
{
id: 'idSAInfo',
label: 'Info',
position: 70,
type: #LINEITEM_REFERENCE,
targetElement: '_SAInfo'
}
]
@UI.hidden: true
UUID;
@UI.selectionField: [ { position: 10 } ]
@UI.lineItem: [ { position: 20 } ]
@UI.identification: [ { position: 20 , qualifier: 'GENERAL' } ]
@EndUserText.label: 'Partner'
PartnerNumber;
@UI.selectionField: [ { position: 20 } ]
@UI.lineItem: [ { position: 30 } ]
@UI.identification: [ { position: 30 , qualifier: 'GENERAL' } ]
@EndUserText.label: 'Sales Date'
SalesDate;
@UI.lineItem: [ { position: 40 } ]
@UI.identification: [ { position: 40 , qualifier: 'GENERAL' } ]
@EndUserText.label: 'Sales Volume'
SalesVolume;
@UI.selectionField: [ { position: 30 } ]
@UI.lineItem: [ { position: 50 } ]
@UI.identification: [ { position: 50 , qualifier: 'GENERAL' } ]
@EndUserText.label: 'Sales Currency'
SalesCurrency;
@UI.identification: [ { position: 60 , qualifier: 'DIFF' } ]
@EndUserText.label: 'Difference Amount'
DifferenceAmount;
@UI.identification: [ { position: 70 , qualifier: 'DIFF' } ]
@EndUserText.label: 'Currency'
DifferenceCurrency;
@UI.identification: [ { position: 80 , qualifier: 'DIFF' } ]
@EndUserText.label: 'Difference Quantity'
DifferenceQuantity;
@UI.identification: [ { position: 90 , qualifier: 'DIFF' } ]
@EndUserText.label: 'Unit'
DifferenceUnit;
@UI.identification: [ { position: 100 , qualifier: 'INFO' } ]
@EndUserText.label: 'Comment'
SaleComment;
@UI.identification: [ { position: 110 , qualifier: 'ADMIN' } ]
@EndUserText.label: 'Created By'
LocalCreatedBy;
@UI.identification: [ { position: 120 , qualifier: 'ADMIN' } ]
@EndUserText.label: 'Created At'
LocalCreatedAt;
@UI.identification: [ { position: 130 , qualifier: 'ADMIN' } ]
@EndUserText.label: 'Local Changed By'
LocalLastChangedBy;
@UI.identification: [ { position: 140 , qualifier: 'ADMIN' } ]
@EndUserText.label: 'Local Changed At'
LocalLastChangedAt;
@UI.identification: [ { position: 150 , qualifier: 'ADMIN' } ]
@EndUserText.label: 'Last Changed At'
LastChangedAt;
}
Du kannst über die IDE Actions auch die Label an den Feldern ergänzen, damit wir saubere und übersetzbare Texte für das UI haben.
Unterentitäten
Für die Unterentitäten generieren wir nur jeweils die Annotationen für das ListItem, da wir eine saubere Tabelle in unserer Entität haben wollen, die Object Page aber im Moment nicht brauchen. Die technischen Schlüssel wie UUID oder Parent ID können wir ausblenden. Die kompletten Ressourcen findest du im GitHub Repository, welches unten verlinkt ist.
Header
Navigierst du aktuell auf die Object Page der App, dann erhältst du im Header einen nicht so hübschen Text. Dieser kommt aktuell nicht aus den UI-Annotationen.
Dafür müssen wir uns den Core Data Service einmal genauer anschauen. Auf Ebene des Headers finden wir die Annotation "EndUserText.label", die für den Core Data Service definiert wurde. Diese wird dann nach der Navigation in der App verwendet. Diese können wir nun entsprechend anpassen.
@Metadata.allowExtensions: true
@Metadata.ignorePropagatedAnnotations: true
@EndUserText: {
label: '###GENERATED Core Data Service Entity'
}
@AccessControl.authorizationCheck: #MANDATORY
define view entity ZBS_C_SASale
Vollständiges Beispiel
Die IDE Action findest du unten verlinkt, wenn du sie auch einmal bei dir im System verwenden willst. Die UI-Annotationen haben wir mit diesem Commit im Repository für unsere RAP Beispiele aktualisiert. Darauf werden wir in den nächsten Beispielen aufsetzen.
Fazit
IDE Actions können unser Leben einfacher machen und etwas mehr Geschwindigkeit in den Alltag der RAP Entwicklung bringen. Die IDE Action heute erlaubt einen Schnellstart in die UI Gestaltung, entweder direkt nach Ausführung des RAP Generators oder dem manuellen Erstellen der Objekte.
Weitere Informationen:
GitHub - My IDE Actions








