A systems engineer’s summer towards fullstack: 3 UI lessons from building complex data products

By Sataponn Phutrakul on August 2, 2019

I am doing a software engineering internship with our dashboard team this summer. I’m also a master’s student in security and cloud computing in the SECCLO programme at Aalto University.

Before moving to Europe, I worked as a Systems Engineer in Thailand, so purely backend work. Last year, I took a web development course in school where I did both front and backend, and when I joined callstats.io and was given a choice of projects to work on for the summer, I decided to take the one most unfamiliar to me - our UI frontend.

Here is a former backend engineer’s take on the three projects I’ve so far worked with on my path towards being proficiently fullstack.


1. Upgrading React 15.X to React 16.X

We’ve happily been using React for several years already. As my very first project here, I upgraded our product from React 15.X to React 16.X. This involved some planning and a whole lot of googling. I first made a list of all deprecations, tested to see if  they worked, removed deprecated libraries and finally fixed errors.

These were especially useful blogposts to review (1, 2, 3).

I did the upgrading manually. For me personally, it was a useful exercise as it familiarised me with our code base, our components, code structures and conventions. If you too are joining a pre-existing project, I would recommend my approach.

If I were to re-do this today though, I would use an automated tool like React Codemod. The project itself was about 4,294 code additions and 4,281 deletions, with 9 PR’s and 134 commits, and it took around one month to complete.


2. Data Chart UI with D3/NVD3

Next, I developed the UI for a dashboard panel called Ops View, our freshly released systems health snapshot view for contact center operators.

This project had already started when I joined the daily SCRUM meetings and read the product and tech specs. My task was to develop the UI according to our UX designer Olga’s specifications. The most enjoyable part of this project was working on the bar chart component as it was the first stacked chart I have ever developed. What made it fun was that it was a rich chart with a real time element.

In our dashboard we use D3.js and NVD3 for chart visualisations.

We have a shared component that generates the chart, which I modified to adhere to the design. As the component was originally meant for another context with another design, I didn’t change the source component too much.

If I could re-do this part, I might look into some other libraries to use. This particular shared-component was quite big and complicated, and I didn't want to spend time changing a lot of things. I’m still proud of in this work though as it almost exactly looks like the design mockup (though I couldn’t find all styling customisations that the library didn’t support).

3. Comparison panel view in our dashboard

Right after the Ops View panel, I worked on a comparison panel for SDP values. This is a brief project that I jumped in mid-way to help with components development. I’ve so far created a new generic shared-component for this feature.

As before, I got a design mockup from our designer Olga.

The most challenging part about this task was integrating the data from the store. I had to create the modal that we use to compare SDPs, and I created a button for this. But the data is not pre-loaded in the beginning, so I had to think of how to trigger data loading for only the two values I wanted when the button is clicked.

I didn't want to make the button tied to the panel, so I didn't put it as a part of the modal component, but received it as a property instead. Since the button is separated from CompareModal component, the component can receive any button as a triggering element. The button has its own onClick defined by the parent component (View for multiple SDPs) for triggering data load. As I need to extend this onClick to open the modal when the button is clicked, I make use of React.cloneElement() inside CompareModal.

React.cloneElement(trigger, {
key: 'compare-button',
onClick: () => {

I searched online how to add more properties to an existing element, and figured it out from there.

Another fun thing I learned was about event handlers or functions as props - before, I used an anonymous function so that I can use variables inside the loop. The problem with anonymous function is that it will worsen the performance of this component. I passed the handler to the child component and accessed the variables inside the component instead.



onEntrySelect = (checked, a, b, c) => {
// Do something

render () {

this.props.sdps.map(sdp => <Entry

--child (Entry)--

handleCheckboxChange = (event) => {
const { onCheckboxChange, sdp } = this.props
const { a, b, c } = sdp
this.props.onCheckboxChange(event.target.checked, a, b, c)
render () {
<input ... type=’checkbox’ onChange={this.handleCheckboxChange} />

Note: ... is omitted code.


Before, when I was a backend engineer, I mostly worked with more system components, like databases and microservices, and testing tended to be more difficult. With frontend, the main differences are that we work only with one component; it’s easier to use any mock data to test; and overall, more focus on the styling and loading aspects of the project.

I’m glad that I jumped at the chance to work on something new this summer. After this experience, I can confidently call myself a fullstack developer.

Tags: callstats.io, Recruiting