Select theme:
In this step from the CRM Application tutorial we will customize the automatically scaffolded CRUD pages.
The contact is a paramount entity in the RadzenCRM application as everything depends on it - opportunities, tasks etc.
Let's add some contacts. We will use some famous members from the tech industry.
salesmanager@demo.radzen.com and SalesManager1@. Those are the credentials of the Jane Smith application user who is a Sales Manager (we added that user in the Customize security article).Bill, LastName: Gates, Email: bill.gates@microsoft.com (probably not his real email), Company: Microsoft.Elon, LastName: Musk, Email: elon.musk@tesla.com (maybe not real too), Company: Tesla.

The first thing we will do is associate the opportunity with the current user and filter the opportunities so:
Services\RadzenCRMService.Custom.cs with the following content.using System;
using System.Data;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Components;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Radzen;
using CRMBlazorServerRBS.Data;
using CRMBlazorServerRBS.Models.RadzenCRM;
namespace CRMBlazorServerRBS
{
public partial class RadzenCRMService
{
private readonly SecurityService security;
public RadzenCRMService(RadzenCRMContext context, NavigationManager navigationManager, SecurityService security)
: this(context, navigationManager)
{
this.security = security;
}
partial void OnOpportunityCreated(Opportunity item)
{
var userId = security.User.Id;
// Set the UserId property of the opportunity to the current user's id
item.UserId = userId;
}
partial void OnOpportunitiesRead(ref IQueryable<Opportunity> items)
{
if (!security.IsInRole("Sales Manager"))
{
var userId = security.User.Id;
// Filter the opportunities by the current user's id
items = items.Where(item => item.UserId == userId);
}
}
}
}
Server\Controllers\RadzenCRM\OpportunitiesController.Custom.cs with the following content.using System;
using System.Net;
using System.Data;
using System.Linq;
using Microsoft.Data.SqlClient;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
using Microsoft.AspNetCore.OData.Results;
using Microsoft.AspNetCore.OData.Deltas;
using Microsoft.AspNetCore.OData.Formatter;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Authorization;
using CRMBlazorWasmRBS.Server.Models;
using CRMBlazorWasmRBS.Server.Models.RadzenCRM;
namespace CRMBlazorWasmRBS.Server.Controllers.RadzenCRM
{
[Authorize]
public partial class OpportunitiesController
{
partial void OnOpportunitiesRead(ref IQueryable<Opportunity> items)
{
var userManager = (UserManager<ApplicationUser>)HttpContext.RequestServices.GetService(typeof(UserManager<ApplicationUser>));
var user = userManager.GetUserAsync(HttpContext.User).Result;
if (user != null)
{
var roles = userManager.GetRolesAsync(user).Result;
if (!roles.Contains("Sales Manager"))
{
// Filter the opportunities by the current user's id
items = items.Where(item => item.UserId == user.Id);
}
}
}
}
}
UserId before submitting the opportunity in AddOpportunity page.protected async Task FormSubmit()
{
try
{
opportunity.UserId = Security.User?.Id;
await RadzenCRMService.CreateOpportunity(opportunity);
DialogService.Close(opportunity);
}
catch (Exception ex)
{
errorVisible = true;
}
}
Since we are manually setting the UserId of the opportunity we should remove the corresponding form field from the Add Opportunity and Edit Opportunity pages.
Let's try if it worked!
salesmanager@demo.radzen.com and SalesManager1@.50000bill.gates@microsoft.comActive02/01/2019Microsoft dealYou should see this.

100000elon.musk@tesla.comWon02/02/2019Tesla dealBut what is that GUID in the User ID column? It is the Id of Jane Smith - the user we have logged in as. Let's display something more user-friendly than a GUID.
Services\RadzenCRMService.Custom.cs with Visual Studio.OnOpportunitiesRead method: items = items.Include(item => item.User);. Here is how it should look like:partial void OnOpportunitiesRead(ref IQueryable<Opportunity> items)
{
if (!security.IsInRole("Sales Manager"))
{
var userId = security.User.Id;
// Filter the opportunities by the current user's id
items = items.Where(item => item.UserId == userId);
}
// Include the User
items = items.Include(item => item.User);
}
,User in the expand parameter value. The expand parameter is similar to a SQL JOIN (and in fact does exactly that behind the scenes).Now let's customize the DataGrid!
@opportunity.User.FirstName.@opportunity.User.LastName.User.FirstName. This tells the DataGrid what property to sort by when the user changes the order by clicking the column header.

If you run the application now it should display the current user name instead of the GUID.

We will improve the look and feel of the Tasks page by using icons in the Task Status and Task Type DataGrid columns.
Run the application and add three tasks with the following properties
Introduction, Opportunity: Microsoft deal, Due Date: 02/02/2019, Task Type: Email, Task Status: Complete.Demonstration, Opportunity: Microsoft deal, Due Date: 03/06/2019, Task Type: Online Meeting, Task Status: In Progress.Negotiation, Opportunity: Microsoft deal, Due Date: 03/26/2019, Task Type: Call, Task Status: Not Started.
Now lets add the icons for the Task Type column.
@task.TaskType.Name.settings_phone (click the ... button
to open the Icon Picker dialog). Set the Visible property to @(task.TaskType.Name == "Call").
This icon will be visible only when the current task type is equal to Call.
Go to the Style tab of the property grid and set VerticalAlign to middle.video_call and set the Visible property to @(task.TaskType.Name == "Online Meeting").email and set the Visible
property to @(task.TaskType.Name == "Email").The Tasks page should now look like this. ![]()
Do the same for the Task Status column.
@task.TaskStatus.Name.check_circle (click the ... button
to open the Icon Picker dialog). Set the Visible property to @(task.TaskStatus.Name == "Complete").
Go to the Style tab of the property grid and set VerticalAlign to middle.cancel and set the Visible property to @(task.TaskStatus.Name == "Not Started").autorenew and set the Visible
property to @(task.TaskStatus.Name == "In Progress").Here is how the end result should look like:

It is time to learn how to create a dashboard page with Radzen Blazor Studio.
Radzen is free to use. You can also test the premium features for 15 days.
Start FreeSelect theme: