Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added section to describe how parts of the UI can be hidden based on user role #940

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions advanced/fiori.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,47 @@ SELECT.from(Books.drafts) //returns all drafts of the Books entity

[Learn how to query drafts in Java.](../java/fiori-drafts#draftservices){.learn-more}

## Use user roles to toggle visibility of UI elements

In some use cases you might want to hide parts of the UI for specific users. This is possible by using the respective UI annotations like `@UI.Hidden` or `@UI.CreateHidden` in conjunction with '$edmJson' pointing to a singleton.

First you would define the [singleton](../advanced/odata#singletons) in your service and annotate it also with ['@cds.persistency.skip'](../guides/databases#cds-persistence-skip) so that no database artefact is created.

```cds
@odata.singleton @cds.persistency.skip
entity Configuration {
key ID: String; //A key is technically not required as it is a singleton, however without it some consumers might run into problems
isAdmin : Boolean;
}
```

Secondly define an on handler for serving the request

```js
srv.on('READ', 'Configuration', async req => {
req.reply({
isAdmin: req.user.is('admin') //admin is the role, which for example is also used in @requires annotation
});
});
```

and thirdly refer to the singleton in the annotation by using a [dynamic expression](../advanced/odata#dynamic-expressions)

```cds
annotate service.Books with @(
UI.CreateHidden : { $edmJson: {$Not: { $Path: '/CatalogService.EntityContainer/Configuration/isAdmin'} } },
UI.UpdateHidden : { $edmJson: {$Not: { $Path: '/CatalogService.EntityContainer/Configuration/isAdmin'} } },
);
Comment on lines +515 to +518
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @schiwekM ,
what is the result here? When I'm logged in as admin, I can't see the Books through this service?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

essentially if you are not the admin than you do not see the EDIT or Create buttons

```

The Entity Container is OData specific and refers to the '$metadata' of the OData service in which all accessible entities are located within the Entity Container. SAP Fiori elements also allows to not include it in the path:

```cds
annotate service.Books with @(
UI.CreateHidden : { $edmJson: {$Not: { $Path: '/Configuration/isAdmin'} } },
UI.UpdateHidden : { $edmJson: {$Not: { $Path: '/Configuration/isAdmin'} } },
);
```
Comment on lines +523 to +528
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is doing the same as the previous snippet when using Fiori Elements, right? In which cases am I not allowed to do omit the entity container?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - EntityContainer is syntactically from an OData PoV correct however in most cases Fiori elements allows you to leave it out. For compatibility I added the entity container notation if something does not work that users can try the syntactically correct one.


## Value Helps

Expand Down
Loading