Skip to content
All work

Phaidra · Software Engineer I

Timelines for Tag Mapping

Solution engineers had to define every sensor tag in a plant as expressions over time, and there was no spec for how that should work. I owned the UI: a timeline per tag, a visual expression builder, and one view of every tag’s timeline so gaps stood out.

ReactTypeScriptVirtualizationProduct design
My part
Product and UI, from an open brief to production
Level
Software Engineer I
Worked with
Solution engineers, design and backend
Stack
React · TypeScript

01The problem

Phaidra's AI works from the sensor data of industrial cooling plants. Before it can, every component in a plant, such as a chiller, and every sensor tag under it has to be mapped to the data behind it. Solution engineers did that mapping, plant by plant.

A tag isn't mapped once. It has a timeline of expressions in NEL, Phaidra's expression language: sums, averages, minimums and maximums over raw point names, each valid between a start and an end time, with exclusion slices where it shouldn't run. A single expression could reference hundreds of point names.

This was the first project I owned, and it came with no spec and no agreed idea of how it should work. My part was the product and UI side: working out with solution engineers what they needed, then building it.

This was internal product work, so there are no screenshots or recreations here. What follows is the thinking, at the level I can share publicly.

02Key decisions

Draw the timeline, don’t list it

Each tag's expressions sit as spans on a time axis, with exclusion slices drawn over them. An overlap or a hole is something you see, not something you work out from a list of timestamps.

Trade-offMore UI to build than a form with start and end dates.

Build expressions by picking, not typing

Solution engineers didn't write Python or NEL. Instead of a text box, they pick point names, assign values and combine them with operations. A visualiser added later shows which point name is used where.

Trade-offThe builder has to cover what the language can express, and stay readable with hundreds of terms in one expression.

One view of every tag’s timeline

On the main tags page, a Gantt-style view lays out every tag's timeline together. Gaps were exactly what solution engineers were looking for, and here they stand out at a glance instead of tag by tag.

Alongside it, a test run locks the table and polls the backend until it reports whether every component and timeline is complete and valid.

Trade-offThousands of rows on one screen, which is where performance became the main problem.

Size the UI for the real data

Some plants had more than 10,000 point names, and the picker dialog crashed. Virtualization fixed the rendering. Then the backend team built a paginated search API, and I moved the picker onto it, keeping pagination and filters in the URL so a search survives a reload and can be shared. As plants grew to thousands of components with hundreds of tags each, I paginated the table and virtualized the timeline view.

Trade-offEvery search is now a round trip to the backend, and the UI has to handle that.

03Outcome

  • No NEL required

    Solution engineers could build and check expressions without writing Python or NEL.

  • Gaps at a glance

    Missing coverage showed up in one view instead of tag by tag.

  • Held up at scale

    Stayed usable as plants reached thousands of components with hundreds of tags each.

esc
↑↓ to move↵ to select