Demo Project

Overview

The demo project is a full implementation of a ready-made Careers module for your Umbraco website. It is based on an entity model created using the Database Extension Kit.

The demo project will show you all the important features of the Database Extension Kit package and provide best practices for front-end integration of entities created and managed using the package.

Running the demo

Pre-requisites

In order to run the demo project locally, you need to have the following software installed on your workstation:

  • Microsoft SQL Server 2019 LocalDB

  • Microsoft Visual Studio 2022 or Visual Studio Code 2022 with Umbraco Project template installed

The demo project can be downloaded from GitHub (https://github.com/hexxu-dev/DBExtensionKitDemo).

The project comes with Umbraco 11 and the Database Extension Kit package already installed and contains a demo database which is powered by MS SQL Server LocalDB.

Setting up the project

Download the project from GitHub and open the solution using Visual Studio 2022 or VS Code 2022.

The project uses SQL Server 2019 LocalDB instance, so make sure that the LocalDB is installed and up to date on your workstation.

The database files (DatabaseExtensionKitDemo.mdf and DatabaseExtensionKitDemo_log.ldf) are placed in the umbraco/Data folder of the project. If you wish to keep them elsewhere, you can move the database files to a different folder on your workstation and modify the settings file appsettings.json and/or appsettings.Development.json accordingly.

The demo project includes a homepage that displays the job list with different filter options, a page to display the detailed information for each job and an integrated application form.

Get started

To get started, pull the source code and launch the project. You can access the back office by navigating to "/umbraco" and using the provided credentials.

Functionality

Entities

There are three entities defined in the Db Extension Kit Admin and Db Extension Kit sections:

Job: Entity can be completely managed in the back office.

Application: Entity is populated through the application form but also manageable in the back office

StatusChange: Entity keeps a history of application status changes. It is populated automatically through the notification handler and can be viewed but not edited in the back office. There are 5 possible values for application status: Submitted, Shortlisted, Interviewed, Employed, and Rejected.

User groups

There are two additional user groups defined: Interviewer and Recruiter. You can sign in as one of them or administrator using these credentials:

Recruiter: recruiter@dbextension.com / recruiter1

Interviewer: interviewer@dbextension.com / interviewer

Administrator: admin@dbextension.com / admin12345

Notification handlers

Every time the user saves an application and changes its status, a new record is added to the StatusChange entity. This is accomplished using an ApplicationSavedHandler:

if (notification.Item.Name == ObjectTypes.Application)
{
    var status = notification.Item.Properties.FirstOrDefault(x => x.Alias == Properties.ApplicationStatus);
    if (status != null && status.Value != null && status.Editor != Aliases.Label)
    {
        var appStatus = jobRepo.GetLastApplicationStatus(notification.Item.Id);
        if (appStatus == null || appStatus.Status != status.Value.ToString())
        {
            appStatus = new StatusChange();
            appStatus.ApplicationFK = notification.Item.Id;
            appStatus.Valid = 1;
            appStatus.Status = status.Value.ToString();
        }
        appStatus.ChangeTime = DateTime.Now;
        var note = notification.Item.Properties.FirstOrDefault(x => x.Alias == Properties.Note);
        appStatus.Note = note != null && note.Value != null ? note.Value.ToString() : "";
        appStatus.User = backOfficeSecurity.BackOfficeSecurity.CurrentUser.Name;
        jobRepo.SaveStatusChange(appStatus);
    }
}

In the application list the interviewer can only see applications with status “shortlisted”. This is done with ApplicationPreSearchHandler

// Some code
if (notification.Item.Name == ObjectTypes.Application)
{
    var allFilters = notification.Search.Filters;
    var statusFilter = allFilters.FirstOrDefault(x => x.Alias == Properties.ApplicationStatus);
    if (statusFilter != null)
    {
        statusFilter.Value = JsonConvert.SerializeObject(new List<string> { ApplicationStatus.Shortlisted });
    }
    HandlerHelper.setListForProperty(notification.Item, Properties.ApplicationStatus, new List<string> { ApplicationStatus.Shortlisted });
}

Finally, we have ApplicationPreLoadHandler, where we make some changes to the Job and Application entities before they are displayed in the edit form.

If the logged-in user is a Recruiter and the current status of the Application entity is as follows:

Submitted: they can edit all properties except Cover Letter, CV Resume, and Application Date. The possible values in the Application status list are Shortlisted and Rejected.

Shortlisted: they can only edit the Bookmarked property.

Interviewed: they can only edit the Bookmarked and Application status properties (with possible values Rejected and Employed).

Employed: they cannot edit anything.

if (notification.DocumentType.Name == ObjectTypes.Application)
{
    var currentStatus = jobRepo.GetLastApplicationStatus(notification.Item.Id);

    if (currentStatus != null)
    {
        switch (currentStatus.Status)
        {
            case ApplicationStatus.Submitted:
                HandlerHelper.setListForProperty(notification.DocumentType, Properties.ApplicationStatus, new List<string> { ApplicationStatus.Shortlisted, ApplicationStatus.Rejected });
                break;
            case ApplicationStatus.Shortlisted:
                setLabelProperties(notification, new List<string> { Properties.Bookmarked });    
                break;
            case ApplicationStatus.Interviewed:
                cleanNote(notification.Item);
                setLabelProperties(notification, new List<string> { Properties.ApplicationStatus, Properties.Note });
                HandlerHelper.setListForProperty(notification.DocumentType, Properties.ApplicationStatus, new List<string> { ApplicationStatus.Rejected, ApplicationStatus.Employeed });
                break;
            default:
                setLabelProperties(notification);
                break;
        }
    }
}

If the logged-in user is an Interviewer, they cannot edit the Job entity. However, in the Application entity, they are only allowed to change the Status property (set it to "Interviewed") and enter a note.

if (notification.DocumentType.Name == ObjectTypes.Job)
{
    setLabelProperties(notification);
}
else if (notification.DocumentType.Name == ObjectTypes.Application)
{
    cleanNote(notification.Item);
    setLabelProperties(notification, new List<string> { Properties.ApplicationStatus, Properties.Note });
    HandlerHelper.setListForProperty(notification.DocumentType, Properties.ApplicationStatus, new List<string> { ApplicationStatus.Interviewed });
}

Last updated