Build HR Management System using MongoDB and ToolJet (Part 2: Company Calendar)
Tags: webdev, javascript, beginners, programming
Published: 2022-07-11 11:33:25

## Company Calendar

To build this application, we will be using one of the amazing features of the ToolJet. We'll use the **Clone App** option to quickly create a clone of the Dashboard application that we created before. Cloning App will save us a lot of time rebuilding the sidebar and main section.

Go to the ToolJet Dashboard, click on the options button on the app that you want to clone and then click on the **Clone App** option.

![clone](https://blog.tooljet.com/content/images/2022/07/Screenshot-2022-07-07-at-5.03.28-AM.jpg)

Once the app is cloned, open the editor and remove all the widgets from the main section and remove all the queries that are there. Don't forget to rename the application from `HR dashboard` to `Calendar` from the top left of the app editor.

> 💡Do not forget to connect MongoDB datasource in each of the 4 apps before building the application.

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-5.24.08-AM.png)

Let's build the UI of the second application which is the Company Calendar.

### Build the user interface of the company calendar

#### Sidebar
We just need to go to the properties of the **Dashboard** button and **Enable** it and **Disable** the **Calendar** button.

#### Main section

- Edit the value of the **Text** widget from **Summary** to **🗓️ Company & Employee leave Calendar** (Yes you can use emojis inside the text widget)
- Now drag a **container** to the left, resize it just enough to place a **text** widget, and **toggle switch** widget inside it. Set the value to the text widget to `Show Leaves` and we will edit the properties of the Toggle switch when we create the queries.

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-3.01.31-PM.png)

- Drag a table widget onto the canvas and resize it according to your preference. Set the **Date Format** as `MM-DD-YYYY HH:mm:ss A Z` , **Default date** to `{{moment().format("MM-DD-YYYY HH:mm:ss A Z")}}` , and **Events** field value to `{{Array.isArray(queries.mergeData.data) ? queries.mergeData.data : []}}`

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-3.03.25-PM.png)

- Drag a Modal widget somewhere below the calendar widget, and we will use an **event handler** on the **button** widget to **show the Modal** and drags widget to it.

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-3.27.25-PM.png)

You can also style the button (and all other widgets) from the **Styles** tab of the widget manager.

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-3.03.52-PM.png)

- Once you have triggered the modal from the button click, drag widgets on the modal to build a form like UI. (as shown in the screenshot below)
- Use **text** widgets as the label for fields like **Event Name** and **Date**, and use **Text input** and **Date picker** widgets for user input fields. In the Date picker widget, set the **Default Date** as `{{moment().format("YYYY-MM-DD")}}` and date Format as `YYYY-MM-DD`

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-3.31.08-PM.png)

- We will use the button widget in the form to run the query for storing an event in the database but since we haven't built the queries yet, we can add just one event handler on the button for closing the modal. We will be adding two event handlers on this button - one to store the event on the database and the other to close this modal.

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-3.35.10-PM.png)

Now the user interface of our second application is done, all we need to do now is to build the queries and connect them with the widgets/UI.

---

### Creating and connecting queries to the UI

#### addHoliday
This query will be used to add new holidays to the database. It will use the data from the fields that are inside the **modal**.

- Create a new MongoDB query, select the **Operation** `Insert One` and in the **Collection** field enter `company_holidays`
- In the Document field, enter `{title: "{{components.textinput1.value}}", start: "{{moment(components.datepicker1.value).toISOString(true)}}" }` - The **title** key will get the data from the text input value in the modal and the **start** key will get the value from the date picker inside the modal but we are also using the **moment.js** library to convert the date format in ISO string.
- You can **Save** the query, and go back to the **button** inside the modal to add the remaining event handler for storing the event in the database.

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-07-at-4.12.12-PM.png)

We have two types of holidays in our database:

- Holidays added by the HR in the database or the official holidays
- Leaves requested by Employees that are approved by the HR

So, by default, we will only display the official holidays on the calendar widget and when the toggle switch is enabled we will display the **Official Holiday + Approved Leaves**.  So, to do this we will build the following queries:

- **companyHolidays** - This query will return the documents that are stored in the `company_holidays` collection that is the official leaves added by HR. There will be an extended JavaScript query `convertDateFormat` that will convert the dates into the valid format accepted by the calendar widget.
- **fetchApprovedLeaves** - This query will return the approved leaves that are those documents that have approved leaves in `employees` collection. There will be an extended JavaScript query `formattedApprovedLeaves` that will covert the leaves into the array of objects and assign keys so that it can be a valid format accepted by the calendar widget.
- **mergeData** - It's a simple JavaScript code that will be connected to the event handler of the **toggle switch** so that it combines the returned data of the above two queries.

#### companyHolidays

- Create a new MongoDB query, select the `Find Many` **Operation** from the dropdown options and then enter the **Collection** name as `company_holidays`
- In the **Options** field, we will use `projection { projection: { _id :0 } }`
- Go to the **Advanced** tab, toggle on the `Run query on page load` , and hit `Save & Run` button
- Next, we will create the `JavaScript code` query - `convertDateFormat`

![clone](https://blog.tooljet.com/content/images/2022/07/Screenshot-2022-07-07-at-5.02.29-PM.png)

#### convertDateFormat

- Create a new query using JavaScript code as the data source, and paste the following code:
```javascript
let holidaysData = queries.companyHolidays.data;
let formattedData = holidaysData.reduce((acc, cv) => {
    acc.push({...cv,start: moment(cv.start).format("MM-DD-YYYY HH:mm:ss A Z"), end:moment(cv.start).format("MM-DD-YYYY HH:mm:ss A Z")})
    return acc;
}, [])
return formattedData;
```

- Hit `Preview` to check the output of the code, and then click `Save & Run` to save and execute the query.
- Go to the **Advanced** tab of the **companyHolidays** query and add the event handler to run the `convertDateFormat` query for On **Success** event.

![clone](https://blog.tooljet.com/content/images/2022/07/Screenshot-2022-07-08-at-4.10.56-AM.png)

#### fetchApprovedLeaves

- Create a new MongoDB query, select the `Aggregate` **operation** and enter the **Collection** name as `employees`
- In the Pipeline field, enter [{$match: {"leaves": { "$elemMatch" : `{ "status":"approved" }}}},{"$project": { "first_name": 1, "email": 1, "leaves": {"$filter": {"input": "$leaves", "as": "leaves", "cond": {"$eq":["$$leaves.status","approved"]}}}}}]`
- Now, go to the **Advanced** tab and enable the `Run query on page load?` option
- Hit the **Save & Run** button
- Now we will write the JavaScript code to format the data returned by this query and then add an event handler on this query to run the JS code.

![clone](https://blog.tooljet.com/content/images/2022/07/Screenshot-2022-07-08-at-4.14.35-AM.png)

#### formattedApprovedLeaves

- Create a new **Run JavaScript Code** query, and paste the following code into the editor:
```javascript
var approvedLeavesArray = queries.fetchApprovedLeaves.data;
var arrayObjects = approvedLeavesArray.reduce((acc,cv) => {
    return acc.concat(cv.leaves.reduce((accLeave, leave)=> {
        accLeave.push(
            {
                "title": cv["first_name"],
                "email": cv["email"],
                "start":	moment(leave["start_date"]).format("MM-DD-YYYY HH:mm:ss A Z"),
                "end":	moment(leave["start_date"]).add(leave["leave_days"], "days").format("MM-DD-YYYY HH:mm:ss A Z"),
            }
        );
        return accLeave;
    },[]));
},[]);
return arrayObjects;
```

- Hit `Preview` to check the output of the code, and then click `Save & Run` to save and execute the query.
- Go to the **Advanced** tab of the **fetchApprovedLeaves** query and add the event handler to run the `formattedApprovedLeaves` query for **On Success** event.

![clone](https://blog.tooljet.com/content/images/2022/07/Screenshot-2022-07-08-at-4.15.12-AM.png)

#### mergeData

- Create a new **Run JavaScript Code** query, and paste the following code into the editor:
```javascript
return components.toggleswitch2.value ? queries.convertDateFormat.data.concat(queries.formattedApprovedLeaves.data) : queries.convertDateFormat.data;
```

- Hit **Preview** to check the output of the code, and then click **Save & Run** to save and execute the query. 

![clone](https://blog.tooljet.com/content/images/2022/07/Screenshot-2022-07-08-at-4.15.31-AM.png)

Now, click on the handle of the **Toggle switch** that we have added, edit its properties and add an Event Handler. Select the `On Change` Event, `Run query` Action, and choose the **mergeData** query.

![clone](https://blog.tooljet.com/content/images/2022/07/Screenshot-2022-07-08-at-4.38.58-AM.png)

Now, you'll be able to see all the events in the calendar and you'll be show/hide leaves from the toggle button.

You can now successfully release this version of the application by clicking the **Release** button on the top right of the app editor.

![clone](https://blog.tooljet.com/content/images/size/w1600/2022/07/Screenshot-2022-07-08-at-4.40.40-AM.png)
---