top of page
Search

Tackling New Challenges in a Familiar Open Source Project

  • Writer: Achsah Jojo
    Achsah Jojo
  • Dec 27, 2024
  • 11 min read

Introduction


In July 2024, I resumed my role as an open-source contributor to the Open Energy Dashboard project. This time, I chose to tackle a new challenge within the project that was outside my comfort zone. Initially, I was concerned that this might limit my exposure to diverse project environments and different programming languages. However, after talking to my mentors, they reassured me that exploring different issues within the same project can deepen my expertise and provide a more comprehensive understanding of the project's architecture. This changed my perspective and got me motivated to start working on this new issue. In this article, I want to share the ups and downs, and the valuable insights I’ve gained as I worked on various user interface enhancement features on this project. 


About the project


Open Energy Dashboard represents an innovative open-source initiative designed to facilitate the visualization of energy data via web browsers. This robust platform empowers individuals and organizations with real-time insights, enabling seamless access to desired energy metrics. This is particularly beneficial for people seeking to monitor energy consumption, its user-friendly interface allows for simple accessibility without the need for technical expertise. This dashboard serves as a tool that offers a simplified yet comprehensive approach to energy monitoring. Its optimized design prioritizes ease of use, catering to a diverse range of users. A prime example of its utility lies in its application within universities, where it aids in tracking electricity usage across various campus facilities such as academic buildings, dormitories, and on-campus residences.

Furthermore, Open Energy Dashboard serves as a valuable resource for individuals aiming to analyze trends in their energy usage over time. This increases awareness and therefore, allows people to make informed decisions towards energy conservation. So if you are not good with technology but you want to track data around energy usage, then Open Energy Dashboard is your best bet!


The arrow shows the sidebar where users can choose a type of graph, a set of groups ( Groups aggregate (sum the usage) of any combination of groups and meters) ,  meters (the basic unit of usage and generally represent the readings from a single usage meter.) etc.. Depending on the graph type you choose, the options differ.
The arrow shows the sidebar where users can choose a type of graph, a set of groups ( Groups aggregate (sum the usage) of any combination of groups and meters) ,  meters (the basic unit of usage and generally represent the readings from a single usage meter.) etc.. Depending on the graph type you choose, the options differ.


The Issue


Create dropdown menus : standard choices for sec in rate #1216


Within OED’s Pages section, there is the Units component which has the the Create/Edit Unit modal which had a text box for entering the "Sec in Rate" as a numerical value. Our  issue was #1216 standard choices for sec. in rate which talks about improving user experience by replacing this text box with a dropdown menu containing predefined standard values—Per Second (1), Per Minute (60), and Per Hour (3600)—while also including an option for custom value entry. This change will involve creating a dynamic dropdown that enables a custom input field when the custom option is selected, ensuring both standard and flexible input methods. In addition to this, we will also have to handle backend adjustments that will be necessary to handle and validate both standard and custom values.

 

Why is this issue important?


This issue is labeled as an enhancement to the existing feature they already have. This issue aims to streamline the input process, reduce errors, and provide administrators with a user-friendly interface that supports both predefined and unique rate entries.


Key Aspects for this issue


For the Create Unit : 


How Sec in Rate looked before our changes
How Sec in Rate looked before our changes


This is the place where we had to do our modifications. As you can see, the Sec in Rate is a text-box where users enter a value of their choice in terms of seconds. So if the user entered 1, then that is equivalent to one second.


The key location of the files that are relevant to solving the issue are as follows: 


  • DesginDocOED/src/client/app/components/GraphicRateMenuComponent.tsx


The purpose of this file was to find a way to loop over the standard rates and see how they are being used. This looping was previously done for a simile dropdown menu for a different component, but the idea and usage of the code was ultimately the same. The circled code effectively transforms the LineGraphRates object into an array of SelectOption objects with translated labels.


  • DesginDocOED/src/client/app/components/unit/CreateUnitModalComponent.tx



This was ultimately the main part of the codebase where we actually implemented our code and made changes. The arrow points at the HTML aspect of the code where we added in our changes such as handleCustomRateChange and so much more. 


For Edit Unit: 


The key location of the file that is relevant to solving the issue was

  • DesginDocOED/src/client/app/components/unit/EditUnitModalComponent.tsx



To make an edit to a unit that was already created, this is the place where we had to do our modifications. Previously, the Sec in Rate was a text-box where users entered a value of their choice in terms of seconds. However, we had to modify it to be a drop-down menu that initially has the created value already in the edit modal. So if previously the sec in rate value was a custom value of 30 or a standard value, then when you click on “edit”, the modal should show the drop-down option preselected to be custom value with the custom textbox showing 30, or the Sec in Rate to show the standard value. 


Codebase overview


Technology Stack 


React and Redux


  • React is being used in this workspace to build various components for OED which is a web application. The components are organized in the components directory and include elements such as DashboardComponent, HeaderComponent, MenuModalComponent, and GroupsDetailComponent. These components utilize React hooks like useState and useAppSelector to manage state and interact with Redux slices, such as appStateSlice and graphSlice. 


Typescript


  • In this workspace, TypeScript ensures type safety in React components and Redux slices. In the CreateGroupModalComponent, it defines the defaultValues object with the GroupData type. TypeScript interfaces manage state and props, catching type-related errors and enhancing IDE tooling. In Redux slices like selectCurrentUserState, TypeScript maintains type-safe state management, reducing runtime errors and improving code maintainability.


Javascript


  • JavaScript is extensively used for both server-side and client-side functionalities. On the server side, JavaScript is utilized in various scripts and services, such as database migration scripts, server configuration and services like createDB.js and migrateDB.js. Additionally, JavaScript is used for logging and version management. On the client side, JavaScript is bundled and managed using Webpack which compiles and optimizes the client-side code.


HTML/CSS


  • HTML and CSS are primarily used within the React components to define and style the user interface. The project uses Webpack for bundling, with loaders configured to handle CSS files (style-loader and css-loader). This setup allows CSS to be written in separate .css files and then imported into JavaScript/TypeScript files, enabling scoped styles for individual components


System Diagram


The "Big Picture" of OED
The "Big Picture" of OED

Flow of Control for Create Unit:


  1. Lets click on create unit on the units page. When this button is clicked, it triggers a front end call to the handleShow function in the file CreateUnitModalComponent. This in turn causes the handleShow function to set the showModal state to true, which causes the modal to be displayed. 



  2. The user then interacts with the modal, filling in the necessary fields. Various handlers update the component's state based on user input such as:

handleStringChange updates string fields.

handleBooleanChange updates boolean fields.



  1. Now we click on the save button and this triggers the handleSubmit function which closes the modal, adjusts the displayable and typeOfUnit fields based on the unit type and suffix and calls the submitCreateUnit mutation to add the new unit to the store.


    Successfully created the unit
    Successfully created the unit



As you can see, after clicking the submit button, there is an alert that shows us that the unit is created, and we can also check to see the unit we created. After creating a new unit and clicking the submit button, the handleSubmit function validates the unit. If valid, it calls submitCreateUnit with the state object containing the data. SubmitCreateUnit is an API that triggers addUnit, which sends a POST request to the server. The server processes this request to insert the new unit into the database.


Flow of Control for Edit Unit :


  1. Lets click on the edit button on the units page. When this button is clicked, it triggers a front end call to the handleShow function in the file EditUnitModalComponent. This in turn causes the handleShow function to set the showModal state to true, which causes the edit modal to be displayed.




  1. The modal shows the various sections filled with values that they had saved in there. When you change and then save them, the state changes and gets updated with the new values.


  1. If you want to discard your progress, you can click on the discard changes button which will reset the values to what they were originally.


Challenges


Confusion with updating state in React


The biggest challenge we had was figuring out how to make a dropdown menu using the appropriate functions that the project already has and how to use hook state from React to manage the state for the drop down menu. We had no previous experience using React so when we had to create hooks to manage the state we were confused on how to customize and incorporate the things we learned in React tutorials into this project. 


What did we do?


The first thing we did was watch React Tutorials and do some pair programming with the team. One of the youtube React Tutorials I watched was “React For Beginners” by Mosh. He walked through how to set up the environment for React and even talked about how to use hook state. However, even after those tutorials and working together, it was difficult figuring out which methods we needed to use, which variables were already created/needed to be created, and where to find the correct functions within this large codebase.  The next thing we tried to do was figure out if there was a similar function somewhere else in the project. Luckily, we found a file called Bar Controls that had a similar drop-down feature that we could use as reference. Lastly, we tried using copilot to give us a template on how to create a drop down menu and incorporated some prompt engineering to ask strategic questions to get an idea on how to use hook state properly. 


Did we just give up? 


Regardless of all this work, we were still stuck, and so we decided to reach out to the maintainer of OED, Steve-Huss Lenderman. We had many team meetings with him where he explained how to find the appropriate files and how to use the correct variables and functions for our project. He also looked at our code multiple times and told us where we went wrong and what we could do to improve. The meetings with him was more concept based, it helped us understand more about the project, such as what the “Create” file does and the purpose of each of the functions and variables. However, since we were new to React, we were also stuck when it came to coding everything out. So to understand the coding aspect of this project, I booked individual and team meanings with CodeDay's help desk. Our team got in touch with Daniel DeAnda ( Software Engineer ) who was able to guide us and explain a coding solution to our issue in a very simple yet effective way. He gave us a visual understanding of how a React state works and how we can use it in our project to save values and update things correctly. He gave us a set of goals that we needed to focus on, and we tried our best to follow those guidelines.


Current Status


We successfully implemented the dropdown menu with the custom value option for the Create Unit page, however, we still have to do the Edit Unit page. Once we get both the pages fixed, we can create a pull request for this issue. 


Solution


How did we get it to work? 




Our first step into solving the problem was to create a hookstate called rate by referring to the BarControls file, which has similar functionality. This hookstate updates when the user selects a new standard rate from the dropdown menu. The next thing I did is when the user selects the custom value option, a textbox should pop up. This was done by creating a hook state called showCustomInput and it needs to be set to true when we want the textbox to be seen. Next, when the user enters a custom value, the hook state for customRate needs to update the value in the custom rate textbox. Then, the initial value of the customRate needs to be set to the previously chosen value of rate. Lastly, I had to make sure that when the submit button is clicked, that the state.secInRate is set to the correct value. 

Once the hookstates were established, I had to create event handlers that can be called when the button is clicked. In this example, handleNumberChange is an event handler for changes in the HTML input element of type number. It extracts the value from the event target, and it has a conditional that analyzes if the value matches a predefined constant of CUSTOM_INPUT. If it does, then it sets the rate to CUSTOM_INPUT, and converts the current rate to a number and sets it as the custom rate, and then displays a custom input field by setting setShowCustomInput to true. If the value does not match CUSTOM_INPUT, it updates the rate with the new value, updates the component's state with the new value converted to a number, and hides the custom input field by setting setShowCustomInput to false.

The next event handler is handleCustomRateChange. This function also handles the changes in the HTML input element of type number. It extracts the value from the event target and converts it to a number. This numeric value is then used to update the state of the component in two ways: first, by calling setCustomRate to set the custom rate, and second, by updating the component's state object with a new property secInRate set to the numeric value. This ensures that both the custom rate and the secInRate property in the state are synchronized with the input value.



When we submitted this to the maintainer, he told us we still had some issues, such as the discard button did not fully reset the sec in rate when clicked and the numbers were not validated. So then we created these functions to address those issues. The customRateValid function checks if a given customRate is a valid integer and greater than or equal to 1, returning a boolean result. The resetState function resets the component's state to its default values by calling setState with defaultValues and then invoking the resetCustomRate function. The resetCustomRate function is a helper that resets the custom rate interval input to its default state by setting the custom rate to 1, the rate to "3600", and hiding the custom input field by setting setShowCustomInput to false. Together, these functions ensure that the custom rate is validated and the state can be reset to its initial configuration.



To use the event handlers and tie everything together, this code snippet defines a form group in a React component using JSX and the reactstrap library. The form group contains a label and a select input for choosing a rate, identified by the ID and name attributes set to "secInRate". The select input's options are dynamically generated by mapping over the entries of the LineGraphRates object, where each option's value is the rate value multiplied by 3600 and the display text is translated using the translate function.

Additionally, there is a custom option with a value of CUSTOM_INPUT and a translated label. When the select input's value changes, the handleNumberChange function is called. If the showCustomInput flag is true, an additional input field for entering a custom rate is displayed. This custom rate input is a number input with a minimum value of 1, and its validity is determined by the customRateValid function. The handleCustomRateChange function is called whenever the custom rate input's value changes. This is how we solved the issue of making a drop-down menu for “Unit Create” in the pages section of OED.


How did we test it? 


To validate the functionality of our code, we initiate the application deployment. First, I start the Docker container for the OED environment. Then, I execute the command `docker compose up` which brings up the necessary services. The application subsequently runs on localhost:3000. Then I log into the system using the admin username and password. Then, I navigate to the Pages section and create a unit/edit a unit. This is how we test our code.





Conclusion


Over the past six weeks, my team and I have made significant progress toward resolving our issue with the Open Energy Dashboard project. This experience has been invaluable, providing us with deeper insights into React, enhancing our collaboration skills, and improving our time management skills. Throughout this journey, I learned the importance of clear communication with both teammates and the project maintainer. Navigating a large codebase can indeed be challenging and sometimes overwhelming, but persistence has proven to be the key to success in open-source contributions. I’m proud of how I pushed through and honed my skills in debugging, coding, and analysis during this summer. Reflecting on the experience, I wish I had utilized the CodeDay help desk earlier rather than waiting till later for assistance. Nevertheless, I’m grateful for the support from my teammates—Emily and Ryan—our mentor, Hannah, as well as CTI and CodeDay for making this experience enriching

 
 
 

Comments


©2025 by Achsah Jojo . Powered and secured by Wix

bottom of page