Finishing touches (Angular)
In this final part of the CRM tutorial we will add a few final features that will make the CRM application more polished.
- Customize the navigation.
- Show the current user picture.
- Allow the current user to update his personal details - first name, last name and picture.
- Create custom design for the login page.
Customize the navigation
We will rearrange the navigation, create a hierarchy, and add icons.
The application navigation typically lives in the Main layout. Layouts are special pages that define common UI components that are shared between multiple pages.
- Open the Main layout in Radzen.
- Select the PanelMenu component. Click the … button to open the Navigation item editor.
- By default it doesn’t display any items because it shows all pages that are marked as “include in navigation” (add and edit pages are excluded by default).
- Click the refresh button to create items for all pages in the application.
- Remove the Opportunity statuses, Task Statuses and Task Types pages. We will add them later under a common parent.
- Move the Home page to the top so it appears first. Set Text to
Dashboard
and Icon tohome
. - Move the Contacts page so it appears second. Set the Icon to
perm_contact_calendar
. - Make the Tasks page third and set the Icon to
work
. - Make Opportunities fourth and set the Icon to
shopping_cart
. - Add a new item with Text
Settings
and Icon:settings
. Set the Visible property to${security.user.isInRole("Sales Manager")}
. This makes this item visible only to members of theSales Manager
role. - Add a child item with Text
Opportunity Statuses
and pick theOpportunity Statuses
page from the Path dropdown. - Then add another child with Text
Task Types
and pick theTask Types
page from the Path dropdown. - Finally add one last child for the
Task Statuses
page.
Now when a member of the Sales Manager
role logs in she would see this navigation.
Members of the Sales Representative
role will see this (not that the Settings menu item is not present).
Show the current user picture
By default the Main layout has a ProfileMenu component which allows users to logout or update their profile. Let’s customize the ProfileMenu to show the current user name and profile picture.
Get the user details
First we have to retrieve the current user details - FirstName
, LastName
and Picture
from the database. The easiest
and most secure way to do that is via custom method.
- Open
server\project.csproj
with Vusual Studio (or theserver
directory with Visual Studio Code). - Open
server\Controllers\ServerMethodsController.cs
. - Decorate the
ServerMethodsController
class with theAuthorize
attribute. It is mandatory for getting the currently logged user via the ASP.NET Core Identity framework.[Authorize(AuthenticationSchemes = "Bearer")] public class ServerMethodsController : Controller { /* snip */ }
- Inject an instance of the
UserManager
ASP.NET Core Identity class.private readonly UserManager<ApplicationUser> userManager; public ServerMethodsController(CrmContext context, UserManager<ApplicationUser> userManager) { this.context = context; this.userManager = userManager; }
- Create a method that returns the current user data.
public IActionResult UserPersonalData() { var userId = User.FindFirst(ClaimTypes.NameIdentifier).Value; var user = userManager.FindByIdAsync(userId).GetAwaiter().GetResult(); return Json(new { FirstName = user.FirstName, LastName = user.LastName, Picture = user.Picture }, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() }); }
Now that we a custom method we can invoke it and store the user details in a page property.
- Open the Main layout.
- Add a new handler for the page Load event.
- Invoke the
UserPersonalData
custom method. - Handle the
Then
event and create a page property calleduserData
with the${result}
.
Time to update the ProfileMenu.
- Select the ProfileMenu component.
- Click the Edit template button.
- Delete the Gravatar component.
- Drag and drop a Label and an Image.
- Set the Text of the Label to
${userData.FirstName} ${userData.LastName}
. - Set the Path of the Image to
${userData.Picture}
. Set Width and Height to32px
and BorderRadius to16px
. - End template editing.
If you run the application from Radzen you will see the current user picture and name in the top right corner.
Update user details
When you enable security for a Radzen application one of the scaffolded pages is Profile (also accessible from the ProfileMenu component in the top right corner).
By default it allows the current user to change their password. In the CRM application we have extended the AspNetUsers table with three new columns - FirstName
, LastName
, Picture
and we want the
user to be able to change them.
Update the user details
First we will create a custom method that updates the details of the current user.
- Open
server\project.csproj
with Vusual Studio (or theserver
directory with Visual Studio Code). - Open
server\Controllers\ServerMethodsController.cs
. - Add the following method which will update the current user details.
[HttpPost] public IActionResult UpdatePersonalData(string firstName, string lastName, string picture) { var userId = User.FindFirst(ClaimTypes.NameIdentifier).Value; var user = userManager.FindByIdAsync(userId).GetAwaiter().GetResult(); user.FirstName = firstName; user.LastName = lastName; user.Picture = picture; var result = userManager.UpdateAsync(user).GetAwaiter().GetResult(); if (result == IdentityResult.Success) { return Ok(); } else { var message = string.Join(", ", result.Errors.Select(error => error.Description)); return BadRequest(new { error = new { message }}); } }
Create the UI
Now let’s create the UI.
- Open the Profile page in Radzen.
- Drag and drop a Tabs component.
- Add two items:
Personal
andPassword
. - Select the
Password
item and move the existing Form there. - Delete the now empty Row.
- Select the
Personal
tab and drag and drop a new Form inside. - Add the following form fields
- Property:
FirstName
, Title:First Name
, Required: Checked. - Property:
LastName
, Title:Last Name
, Required: Checked - Property:
Picture
, Title:Picture
, Type:file
, Required: Checked
- Property:
- Let’s now populate the form. Invoke the
UserPersonalData
custom method and create a property calledpersonalData
set to${result}
. - Set the Data property of the form to
${personalData}
. This will data-bind the form to thepersonalData
property - the form fields will show the corresponding members of thepersonalData
page property.
The final step is to use the UpdatePersonalData
method when the user submits the form.
- Add a new handler for the form Submit event.
- Ivoke the
UpdatePersonalData
custom method.- Set the firstName parameter to
${event.FirstName}
- Set the lastName parameter to
${event.LastName}
- Set the picture parameter to
${event.Picture}
- Set the firstName parameter to
- Display a notification in the Then event to let the user know that their details have been updated.
- Display a notification in case of an error.
Custom login page
Finally let’s create a custom login page by editing both the Login layout and page.
Login layout
We will add a background image that will cover the whole page. Also we will add the CRM application logo.
Add the assets
Radzen allows you to use images seamlessly. For this demo we will use a background and logo. Download those files and add them as assets in the application.
Set the background image
- Open the Login layout.
- Drag an Image component and drop it before the existing row component.
- Set the Path of the image to login-background.png (click … to use the asset picker).
- Set Width and Height to
100%
. Set Position toabsolute
. Set Top and Left to0
. This will make the image cover the whole page.
Center the row
We now want to center the login form in the page (both horizontally and vertically).
- Select the Row component.
- Set Horizontal Alignment and Vertical Alignment to
Center
. - Go to the Style tab. Set Position to
absolute
, Top, Right, Bottom and Left to0
. Set Margin to0
.
Specify column settings
- Select the Column component.
- Set the XL size to
3
units, LG to4
, MD to5
and SM to8
. - Set Vertical Alignment and Horizontal Alignment to
None
. - Go to the Style tab and set Padding to
0px
.
Add logo
- Drag an Image component and drop it in the Card component.
- Set Path to
logo.png
. - Set Width and Height to
128px
. Set BorderRadius to64px
. This will make the logo a circle. - Let’s center the image. Set Display to
block
. Set Right and Left Margin toauto
. - Now let’s make the image pop out of the card a bit. Set Top Margin to
-72px
.
Login page
Let’s now customize the Login page by using a TemplateForm instead of the Login component.
Create the login form
- Open the Login page.
- Delete the existing Login component and its parent row and column.
- Drag and drop a TemplateForm then delete its content.
- Drag and drop a TextBox inside the TemplateForm. Set its Name to
Username
and Width to100%
. Set top Margin to16px
. - Drag a Label before the TextBox. Set its Text to
Username
and pickUsername
from the Component dropdown. Set Display toblock
so the TextBox starts on the next line. - Drag and drop a Password. Set its Name to
Password
and Width to100%
. - Duplicate the Label. Set Text and Component to
Password
. - Drag and drop a Button. Set Text to
Login
, ButtonType tosubmit
, Width to100%
and top Margin to16px
.
Perform the login
Now to actually perform the login.
- Handle the Submit event of the Template form.
- Invoke the
login
data source method. Set the username parameter to${event.Username}
and password to${event.Password}
. - Handle the Error event and display a notification if the login fails for some reason.
That is all!
Complete source
The complete source of this application (with a few additional changes that are mostly cosmetic) is available in the Radzen github repository.