mohd-faraz

_blogs

// blogs / 20260710.md

Dev Log: July 10 Wrap-up

2026-07-10
#Chatbot#ReportingEngine#Refactoring#Dashboard#UX

Overview

Today was a bit of a mixed bag—spent a good chunk of time jumping between some UI polish on our chat components and diving into the guts of the reporting engine to handle more complex data grouping. It felt productive, though. I like days where I can balance quick CSS/HTML tweaks with some heavier logic.

What I Worked On

Making the chat feel more 'human'

I spent some time today cleaning up the chat embed component. One of those small changes that actually makes a huge difference in feel was changing the loader text from "thinking..." to "Typing...". It’s funny how much more responsive a bot feels when it uses human-centric language.

I also added a 'New Chat' button so users aren't stuck in old sessions, and implemented a silent start trigger. Basically, if a session is fresh, the system can now fire off a hidden greeting to get the conversation moving without the user having to type first.

Tackling segment grouping in reports

The biggest technical hurdle today was in the dynamic print engine. I needed to implement a way to group data based on specific segments. The goal was to let templates group nested records by specific keys and show a clear heading for each group.

I ended up adding some configurable fields to the segment schema like required_grouping and default_grouping_keys. The logic for processing this was getting a bit messy, so I refactored the grouping execution into a reusable helper. It's much cleaner now and avoids a ton of code duplication when we process different types of data objects.

Here’s a sanitized look at how I’m handling the grouping logic now:

private List<Map<String, Object>> processDataGrouping(
        List<Map<String, Object>> rawRecords,
        String keysToGroupBy) {

    if (rawRecords == null || keysToGroupBy == null) return null;

    String[] keys = keysToGroupBy.split(",");
    // Using a LinkedHashMap to maintain order while grouping
    Map<String, List<Map<String, Object>>> groupedMap = new LinkedHashMap<>();

    for (Map<String, Object> record : rawRecords) {
        String groupLabel = resolveHeading(record, keys);
        groupedMap.computeIfAbsent(groupLabel, k -> new ArrayList<>()).add(record);
    }

    // Return as a structured list for the template engine
    return formatForOutput(groupedMap);
}

Helpdesk Dashboard Tweaks

Finished the day with some quick updates to the Helpdesk module. We renamed the dashboard title to be more specific to the project and added a severity filter. The team also needed more visibility on critical items, so I added a new KPI badge specifically for "Post Go-live Blockers." It's one of those metrics nobody wants to see go up, but everyone needs to track.

Wrapping Up

Most of the heavy lifting for the reporting engine is done, which is a relief. Tomorrow, I’ll probably spend some time testing those group headings with different data edge cases to make sure the labels don't break when a key is missing. Catch you then.