Save $100 with promo code CHEERS2025

As we are looking forward to an incredible 2025, enjoy our end-of-year promotion! Valid now through January 6th.

See Pricing

Still using Radzen Studio?
Achieve more with Radzen Blazor Studio

Radzen Blazor Studio is our new flagship product and vision of how rapid Blazor application development should be done.

Go to Radzen Blazor Studio

Customize CRUD pages (Angular)

In this step from the CRM Application tutorial we will customize the automatically scaffolded CRUD pages.

  • Start by adding some contacts
  • Customize the Opportunities page
    • Associate an opportunity with the current application user.
    • Display the user first and last name in the opportunity DataGrid.
  • Add icons for the Task Status and Task Type columns in the Tasks page.
  • Add search capabilities to the Contacts page.

Add some contacts

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.

  1. Open the Contacts page in Radzen.
  2. Select the DataGrid component and remove the ID column as we don’t need it.
  3. Run the application from Radzen.
  4. Log in with 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).
  5. Navigate to the Contacts page.
  6. Add two contacts:
    • FirstName: Bill, LastName: Gates, Email: bill.gates@microsoft.com (probably not his real email), Company: Microsoft.
    • FirstName: Elon, LastName: Musk, Email: elon.musk@tesla.com (maybe not real too), Company: Tesla.

Customize the Opportunities page

Associate opportunities with users

The first thing we will do is associate the opportunity with the current user and filter the opportunities so:

  • Members of the Sales Representative role see only their opportunities.
  • Members of the Sales Manager role see all opportunities.

We do that by customizing the server-side code of the Radzen application.

  1. Stop the running application.
  2. Open server\project.csproj with Vusual Studio (or the server directory with Visual Studio Code).
  3. Add a new file server\Controllers\CRM\OpportunitiesController.Custom.cs with the following content.
    using System.Linq;
    using System.Security.Claims;
    using Microsoft.AspNetCore.Authorization;
    
    namespace RadzenCrm.Controllers.Crm
    {
        using Models.Crm;
    
        [Authorize(AuthenticationSchemes = "Bearer")]
        public partial class OpportunitiesController
        {
            partial void OnOpportunityCreated(Opportunity item)
            {
                var userId = User.FindFirst(ClaimTypes.NameIdentifier).Value;
    
                // Set the UserId property of the opportunity to the current user's id
                item.UserId = userId;
            }
    
            partial void OnOpportunitiesRead(ref IQueryable<Opportunity> items)
            {
                var role = User.FindFirst(ClaimTypes.Role).Value;
    
                if (role != "Sales Manager")
                {
                    var userId = User.FindFirst(ClaimTypes.NameIdentifier).Value;
    
                    // Filter the opportunities by the current user's id
                    items = items.Where(item => item.UserId == userId);
                }
            }
        }
    }
    

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.

  1. Open the Add Opportunity page.
  2. Select the Form component.
  3. Delete the UserId form field.
  4. Repeat steps 1 to 3 for the Edit Opportunity page.

Let’s try if it worked!

  1. Run the application from Radzen.
  2. Log in with salesmanager@demo.radzen.com and SalesManager1@.
  3. Add a new opportunity with the following details:
    • Amount: 50000
    • Contact: bill.gates@microsoft.com
    • Opportunity Status: Active
    • Close Date: 02/01/2019
    • Name: Microsoft deal

You should see this.

Display the first and last name in the Opportunities DataGrid

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-friendy than a GUID.

  1. Open the Opportunities page in Radzen.
  2. First we have to get the current user as an entity so we can use its properties in the DataGrid.
  3. Select the DataGrid component and edit its LoadData event handlers.
  4. Append ,User in the $expand parameter value. The $expand parameter is similar to a SQL JOIN (and in fact does exactly that behind the scenes). Click the Done button to close the Event Editor.
  5. Go to the Properties tab of the property grid and edit the Template of the User ID column.
  6. Drag and drop a Label component. Set its Text property to ${data.User.FirstName} ${data.User.LastName}.
  7. Close by clicking the End template editing button.
  8. Finally set the FilterProperty and SortProperty of the User ID column to 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.

Add icons in the Tasks DataGrid

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

  1. Title: Introduction, Opportunity: Microsoft deal, Due Date: 02/02/2019, Task Type: Email, Task Status: Complete.
  2. Title: Demonstration, Opportunity: Microsoft deal, Due Date: 03/06/2019, Task Type: Online Meeting, Task Status: In Progress.
  3. Title: 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.

  1. Open the Tasks page in Radzen.
  2. Select the DataGrid component.
  3. Edit the Template property of the Task Type column.
  4. Drag and drop a Label component and set its Text property to ${data.TaskType.Name}.
  5. Drag and drop an Icon component. Set the Icon property to settings_phone (click the button to open the Icon Picker dialog). Set the Visible property to ${data.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.
  6. Duplicate the existing icon by right-clicking it and picking the Duplicate option. Change the Icon property to video_call and set the Visible property to ${data.TaskType.Name == 'Online Meeting'}.
  7. Duplicate the last icon. Change its Icon property to email and set the Visible property to ${data.TaskType.Name == 'Email'}.
  8. Click End template editing.

The Tasks page should now look like this.

Do the same for the Task Status column.

  1. Edit the Template of the Task Status column.
  2. Drag and drop a Label component and set its Text property to ${data.TaskStatus.Name}.
  3. Drag and drop an Icon component. Set the Icon property to check_circle (click the button to open the Icon Picker dialog). Set the Visible property to ${data.TaskStatus.Name == 'Complete'}. Go to the Style tab of the property grid and set VerticalAlign to middle.
  4. Duplicate the existing icon by right-clicking it and picking the Duplicate option. Change the Icon property to cancel and set the Visible property to ${data.TaskStatus.Name == 'Not Started'}.
  5. Duplicate the last icon. Change its Icon property to autorenew and set the Visible property to ${data.TaskStatus.Name == 'In Progress'}.
  6. Click End template editing.

Here is how the end result should look like:

The final task from this help article is to add search capabilities to the Contacts page.

Add search UI components

First we will add the search UI components - a TextBox and a Button.

  1. Drag and drop a TextBox component.
  2. Create a page property called contactFilter. Move the Set property action to be first. You can check the page properties help article for more info.
  3. Set the Value of the TextBox to ${contactFilter}. Now when the user types in the TextBox the contactFilter property will update.
  4. Drag and drop a Button component after the TextBox. Set its Text property to Search.
  1. Add an event handler for the Click event of the search button.
  2. Set the Type of the event handler to Execute Code and Code to this.grid0.load(). This will make the DataGrid component load when the user clicks the button.
  3. Select the DataGrid component and open the event editor of the LoadData event.
  4. Open the Query builder to specify the filtering query which will do the search.
  5. Add a new Filter Group and set its logical operation to OR.
  6. Add a new filter with the for the Company property, with Contains comparison and '${contactFilter}' value.
  7. Do the same for the FirstName, LastName and Email properties.

You can now search for contacts.

It is time to learn how to create a dashboard page with Radzen.