Techies.

Using and Configuring C#Bot CRUD Collection

This article shows and example of how you can leverage the C#Bot CRUD Collection component to create a custom dashboard


Video

Content

This article walks you through creating a configuring a custom crud tile in C#Bot.

Scenario

I am a user who wishes to make an application to my team leader (maybe applying to take leave). I want to be able to log in to a website and see a list of my applications and the review status for each of them in a dashboard.

Entity Model

The entity model has a few basic users with user behaviour and an entity named Application which has a workflow behavior. All associations are one-to-many and have source optional and target optional set to true.

entityDiagram.png

UI Model

The UI model has a page Dashboard, which has Is Home Page set to true. The Dashboard page also has a Custom Tile named Dashboard.

uiModel.png

Security Model

The user entity Admin has full permissions, no visitor access is given to the site, and in general the security is very relaxed.

securityModel.png

Frontent

ApplicationEntity.tsx

Find the protected region Add any custom attributes to the model here, turn it on and add the lines of code shown below.

// % protected region % [Add any custom attributes to the model here] on begin
    public applicantEmail: string;
    public workflowStateName: string;
    // % protected region % [Add any custom attributes to the model here] end

Dashboard Tile.tsx

Find the protected region Add any extra imports here, turn it on and add the lines of code shown below.

// % protected region % [Add any extra imports here] on begin
import Collection from 'Views/Components/Collection/Collection';
import { observable, runInAction } from 'mobx';
import { ApplicationEntity } from 'Models/Entities';
import axios from 'axios';
import { ICollectionHeaderProps } from 'Views/Components/Collection/CollectionHeaders';
// % protected region % [Add any extra imports here] end

Find the protected region Add class properties here, turn it on and add the lines of code shown below.

// % protected region % [Add class properties here] on begin
    @observable
    private applications: ApplicationEntity[] = [];
    // % protected region % [Add class properties here] end

Find the protected region Override contents here, turn it on and add the lines of code shown below.

// % protected region % [Override contents here] on begin
        const tableHeaders: ICollectionHeaderProps<ApplicationEntity>[] = [
            {
                name: 'applicantEmail',
                displayName: 'Applicant (Email)'
            },
            {
                name: 'workflowStateName',
                displayName: 'Review Status'
            }
        ];

        contents = (
            <>
                <h4>My Applications</h4>
                <Collection 
                    headers={tableHeaders}
                    collection={this.applications}
                />
            </>
        );
        // % protected region % [Override contents here] end

Find the protected region Add class methods here, turn it on and add the lines of code shown below.

// % protected region % [Add class methods here] on begin
    componentDidMount(): void {
        axios.get('api/entity/ApplicationEntity/applications')
            .then(({data}) => runInAction(() => this.applications = data))
            .catch(error => console.log(error))
    }
    // % protected region % [Add class methods here] end

Backend

ApplicationEntityDto.cs

Find the protected region Add any extra attributes here, turn it on and add the lines of code shown below.

// % protected region % [Add any extra attributes here] on begin
        public string ApplicantEmail {get; set;}
        public string WorkflowStateName {get; set;}
        // % protected region % [Add any extra attributes here] end

ApplicationEntityController.cs

Find the protected region Add any extra class variables here, turn it on and add the lines of code shown below.

// % protected region % [Add any extra class variables here] on begin
        private readonly IUserService _userService;
        private readonly UweDBContext _dbContext;
        // % protected region % [Add any extra class variables here] end

Find the protected region Add any extra constructor arguments here, turn it on and add the lines of code shown below.

// % protected region % [Add any extra constructor arguments here] on begin
            ,IUserService userService
            ,UweDBContext dBContext
            // % protected region % [Add any extra constructor arguments here] end

Find the protected region Add any extra constructor logic here, turn it on and add the lines of code shown below.

// % protected region % [Add any extra constructor logic here] on begin
            _userService = userService;
            _dbContext = dBContext;
            // % protected region % [Add any extra constructor logic here] end

Find the protected region Add any further endpoints here, turn it on and add the lines of code shown below.

// % protected region % [Add any further endpoints here] on begin
        [HttpGet]
        [Route("applications")]
        [Authorize]
        public async Task<IEnumerable<ApplicationEntityDto>> GetDashboardApplications()
        {
            var user = await _userService.GetUserFromClaim(User);

            var applications = _dbContext.ApplicationEntity
                .Where(application => application.ApplicantId == user.Id)
                .Include(application => application.Applicant)
                .Include(application => application.WorkflowStatess)
                .ThenInclude(workflow => workflow.WorkflowStates);

            return applications.Select(application =>
                new ApplicationEntityDto(application)
                {
                    WorkflowStateName = application.WorkflowStatess.First().WorkflowStates.StepName,
                    ApplicantEmail = application.Applicant.Email
                }
            );

        }
        // % protected region % [Add any further endpoints here] end

Result

dashboard.png

Last updated: 27 August 2020


Related articles