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@
.50000
bill.gates@microsoft.com
Active
02/01/2019
Microsoft deal
You should see this.
100000
elon.musk@tesla.com
Won
02/02/2019
Tesla deal
But 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.
Download NowSelect theme: