# Lead Statuses

## Backend

As for now, in app settings we can control Leads Statuses.

Backend part of this you will find in leads module.

***your\_project/api/src/leads/***

In service file you will find methods related to lead statuses. They represent the usual CRUD methods. Need to mention applyDefaultLeadStatuses that add 4 default statuses to each team when it's creates, and updateStatusOrder - it controls status order.

ApplyDefaultLeadStatuses uses defautStatuses enum from ***api/src/common/constants/lead-status.enum.ts.***

Method:

```typescript
    async applyDefaultLeadStatuses(teamId: string) {
        return Promise.all(
            defaultStatuses.map(async status => {
                return await this.leadStatusRepository.save({
                    name: status.name,
                    primaryColor: status.primaryColor,
                    secondaryColor: LeadSecondaryColorMap[status.primaryColor],
                    team: { id: teamId },
                });
            })
        );
    }
```

{% hint style="warning" %}
N.B. Status order - this is the order followed by each status. From the lowest, or the very first, to the most important or the highest, etc.
{% endhint %}

Special mention need that how secondary color forms. In createStatus you will find regular TypeORM create method with secondaryColor field. For its formation is used LeadSecondaryColorMap from ***api/src/common/constants/lead-status-color.enum.ts.***

Also how `statusOrder` forms. Take a look at this field from `Lead Status entity`.

```typescript
    @Generated('increment')
    @Column()
    statusOrder!: number;
```

It uses Generated method with 'increment' parameter from TypeORM library. This will auto-increment status order for every new status. Remember that each team has it's own set of lead statuses. Each of them will have their orders that works only within each team.

Method from service:

```typescript
    async updateStatusOrder(statuses: UpdateStatusOrderDto[]) {
        for (const status of statuses) {
            await this.leadStatusRepository.update({ id: +status.id }, { statusOrder: status.statusOrder });
        }

        await this.leadStatusRepository.save(statuses);
    }
```

This method is pretty regular, but it's very interesting how you can do it on frontend part.

## Frontend

You can find the application settings page in the menu

<figure><img src="/files/4h1Cwz5D97QDEg7uA7C0" alt=""><figcaption></figcaption></figure>

or by typing&#x20;

<http://your\\_website/settings>

You will find the main page file in

***your\_project/ui/src/pages/Settings***

At the moment, there you can see only one component with statuses. In the first version of the application, only these settings will be available. Let's get to them.

***your\_project/ui/src/components/settings/***

Inside you can find all the elements that implement CRUD but let's pay attention to what the mechanics of changing the order of statuses are implemented.

The main mechanism for working on changing the order of statuses is associated with the use of the Drag and Drop library in combination with Frame Motion animations. Just pull the status to another place and you will change their order in the application.

#### How is this done?

The items themselves and the entire list are wrapped in **DnD kit** components with **Framer Motion** animations. You can read more about this library in their official library.

When you put the status in another place, a call is made to the server which changes the order of the status.

```javascript
const handleDragEnd = async event => {
        const { active, over } = event;

        if (active.id === over.id) {
            return;
        }

        const activeIndex = getStatusPosition(active.id, statuses);
        const overIndex = getStatusPosition(over.id, statuses);

        if (activeIndex !== overIndex) {
            const newStatuses = arrayMove(statuses, activeIndex, overIndex);

            const updatedOrder = newStatuses.map((status, index) => ({
                ...status,
                statusOrder: index + 1,
            }));

            try {
                await updateStatusOrder(updatedOrder);
                setStatuses(updatedOrder);
            } catch (error) {
                console.error('Failed to update status order:', error);
            }
        }
    };
```

This function handles the end of a drag event.

Step-by-step breakdown of how it works:

1. **Extract Elements**: The function retrieves the **active** (dragged element) and **over** (element where the dragged item is dropped) properties from the **event** object.
2. **Check for Same Position**: If **active.id** is the same as **over.id**, meaning the item was dropped in the same spot it was picked up from, the function exits without making any changes.
3. **Get Indexes**: Using the **getStatusPosition** function, it determines the indexes of **activeInde**<mark style="color:blue;">**x**</mark> and **overIndex**, representing the positions of the items in the **statuses** array.
4. **Check for Position Change**: If the indexes **activeIndex** and **overIndex** are different, meaning the item was moved, the function proceeds with reordering.
5. **Move Elements**: The **arrayMove** function rearranges the elements in the **statuses** array to reflect the new position, creating **newStatuses**.
6. **Update Order**: The **newStatuses** array is then mapped to create **updatedOrder**, where each item is assigned a new **statusOrder** based on its index (position).
7. **Save Changes**:
   * The **updateStatusOrder** function is called, likely to update the item order on the server or in global state.
   * If the update is successful, the local state **statuses** is updated with **setStatuses(updatedOrder)**.
   * If an error occurs, the function logs a message in the console.

You may notice that here are not used notifications that can be found in other handlers. Notification is not everywhere and is not always needed.

### Permissions

Not all team members can edit statuses. Please read related block about permissions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://intercode.gitbook.io/intercode-saas-kit/pages/app-settings/lead-statuses.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
