Lead Statuses

Here you will find all the information how lead statuses works.

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:

    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 },
                });
            })
        );
    }

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.

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.

    @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:

    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

or by typing

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.

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 activeIndex 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.

Last updated