On the first and second day of last week, I continue modified the item-detail panel and the width of the web page when the side drawer is opened. In the item-detail panel, I used Array.join() method to separate the category type with a comma in the table. I also used carousel method to display multiple images in the panel. For the search function, I used Array.every() method to ensure that each term in search query is present in the item name.
Mr. Peter give me a task that create a Store page which should include CRUD function. He mentions that this page should consists the entity details. This store page is getting data from the API. At first, I created a panel that show the detail of the store. Then, I pulled out the branch and merge it into my existing feature branch which is “store” in order to use Redux.
For the CRUD function, I refer to the “Customer” which created from my colleague and make some changes that fulfil the requirement of “Store” page. So far, I completed the “Create” and “Update” function, the “Read” function I will complete in next week to show the list of the store with the search function.
Implementation of API
Last week, I finished integrating the API into the React website. This API will establish a data link between the database and the system. At first, I didn’t realize the APIprovided by my colleagues had many methods such as getByIdAsync, getListAsync, updateAsync, deleteAsync, and createAsync. In my development, I only used getListAsync for displaying purposes. I did not concentrate on using the API to create, update, and delete entities. However, the getListAsync method will not return information about a specific customer. I need to use getByIdAsync to view all of the data for a single customer. For example, the addresses types were missing from getAsync but were present in getByIdAsync. Thus, I need to use all the methods for the customer page.
When the system was first being developed, I struggled with the create new customer and modify an existing customer. It’s because they’ll be using the same module to display the data. I used to just pass the length of the array as the ID of a new customer, but I changed my mind. When setting the value, I will now pass the ID as undefined to the module and/or method. Because the react hook form requires the use of setValue when passing data to the module, I used the “||” to determine the data’s existence. When getByIdAsync returns an undefined Id, I setValue to null and convert this file into a create customer form.
Aside from that, the provided API lacks of customer types yet includes the address name and address remark. Following Mr. Peter’s clarification, I should revise the customer page prototype to include the address name and address remark instead. Fortunately, these minor changes are straightforward; I only need to add two new text boxes to the address column. Furthermore, I successfully eliminate the duplicate code. The code was now shorter, and fewer files were required for each page.
By the end of the week, I couldn’t connect to the API’s POST function. I informed Mr. Peter and will resolve the issue within the next week. I believe that the customer page will be completed within the next week, at which point I will embark on the journey of creating the main page. I only have one month to finish the main pages, and I’m hoping to finish them before the internship ends.
Solving Problems in Server and MongoDB
This week I continue to solve the API problem that I encountered last week. The issue I ran into last week was that Postman was not able to establish a connection to the database. After the guidance and advice from Mr. Peter, I can run the API on Postman correctly. The docker-compose.yml file contained some missing information, which caused the issue. Upon incorporating the data and reconstructing the docker-compose.yml, I successfully executed the API through Postman.
This week, I also ran into a problem where I couldn’t get software to connect to the database. I have attempted to establish a connection with the server and launch software again in order to access my database. The database system is in recovery mode or the database connection has timed out, according to the error message I received. Despite my attempts to use Google Chrome to remedy the issue, the error persisted. I thus told Mr. Peter about this mistake right away. He explained to me that the issue was caused by an excessive amount of memory in the log file. So, after solving the problem, I was able to run the database again.
In addition, Mr. Peter discovered that third parties had gained access to the data kept in our MongoDB. This is a result of the deletion of the database that held the item data. The MongoDB server also established a new database named “READ_ME_TO_RECOVER.” In order to prevent anyone else from accessing our MongoDB server in the future, Mr. Peter quickly shuttered it. He then built a new server and added a far more complex login and password to prevent unauthorized users from readily accessing our MongoDB.
After Mr. Peter fixed the MongoDB issue the following day, no additional new connections were made, indicating that as of right now, no hacker was attempting to steal our data. But Mr. Peter has told me to keep a close eye on the MongoDB and let him know if someone hacks our data once more. This week, I have attempted to access the MongoDB, but it continues to fail. In order for Mr. Peter to try to debug and identify the issue, he has asked me to push my workings to the feature branch.
Resolving Bugs Arise of SignalR Progress Bar Implementation
During the past week, my primary goal was to address various bugs in the modified section of the application where the progress bar with SignalR had been recently implemented. As mentioned in my previous blog, a critical issue arose when attempting to save changes after the loading bar reached 100 of saving batch data, triggering an error message stating “batch too large.” After thorough debugging, it was identified that the problem originated from Cassandra. To resolve this, Mr. Peter showed me a temporary solution by directly overwriting the save changes in the database. The rationale behind this approach is the potential removal of Cassandra usage in the future.
The next bug involved the progress bar not advancing and continuously displaying “Queue (0/0)” after the user clicked ‘cancel’ during a previous process. This issue was rectified by making minor changes to the conditional statements. However, the most time-consuming bug to diagnose was an unresponsive UI on the cancel button during data generation. This occurred after the user initiated another process in the same section. Initially, a thread-related problem was suspected, but even after converting certain parts of the code to asynchronous, the issue persisted.
Towards the end of the week, I inserted a line of code to monitor the changes in the progress bar and its GUID. It became evident that with each cancellation, multiple GUIDs were managing the progress in the subsequent progress bar. My initial hypothesis was that the cancellation process might not be completed and the multiplication of GUID during each cancellation could be the root cause of the lagging issue. Unfortunately, by the end of the week, I was unable to resolve this particular section of the code.
Modifying some Features from Supervisor’s Suggestion
This week I display what I have done so far to Mr. Peter. He pointed out several points that I should change. First of all, he suggests me prevent any hardcoded way because all of the data will get from API. Therefore, the hardcoded way will lead me to write the same function again and again and I use the .map function to overcome this issue. He also suggests that the naming of the folder and the file must be consistent. This is due to the reason that easier to let other find the file according to the structure. For example, every file or the folder of the first letter must be capital and the CSS style must be renaming it with the same name of the file that use the CSS file.
On the other hand, he also suggests the position of the “Search bar” need to change to on the top center of the page. This “Search” is the most frequently use in the page, therefore, I make the width of the search bar 70% to the width of the page and place between the “Header” and “Navigator”. In the item-detail panel, he mention that there will be a several number of images need to display, not only one, so, I am consider to use carousel method to display the images.
Lastly, he suggests the general components like the “Header” which can use anywhere put into the main file so that any page can display the header code at one time, no need every file to import this component again. Since, I change the location of the file, so I need to rename the path and the division of the header and the main content of the page need to change.
Adding Some Features and Styling the Task from Last Week
Continuing the task from last week, I modified the arrangement of the item box in the main page as well as the “price” and the “stock in the item box itself horizontally by solving it with CSS style and I controlling the spaces between each of the item box. Besides that, I also adding two navigator tabs with “Code” and “Record/Stock” labels and adding the new table in the item details panel. In the content of the “Code” tab, I added the Barcode of the item and arrange them horizontally and space evenly. In the content of the “Record / Stock” tab, I added the “History Sales Record” table and “Stock” table and space evenly between each of them.
I also modifying the styles of the item detail panel according to the colour, effect and position of the elements inside the panel, especially the division between them. I separate them into 3 part, the main part includes the image, name, stock, price, UoM and some description or remark, the second part include the navigator tab and the content of it, and the third part include the extra information such as the attributes.
On the other hand, I added the additional table as a panel to show the detail of the item and it will pop out when I clicked the particular button in the item detail panel. I also added the dropdown menu and it’s sub navigator, the “Filter” sidebar which is on the right-hand side of the item page – able to filter the item according to the brand of the item and able to sort the price from lower price to lower or vice versa and yet the “Pagination” feature which will control the page of maximum 20 items per page.
Lastly, I modified the position of the drawer navigation to the left-top of the Item Page and push all the elements to the right when I clicked the hamburger icon. Previously, it was appearing under the item list, Mr. Peter suggest me to create a new page that include the drawer and the header only to settle this problem, but actually it is just a division problem, I changed the arrangement of the code according to the division to overcome this problem. I also modified the styling of the dropdown menu with the colour, hover effect and the width of the menu list.
Addition of Filter and Button for UI Enhancement
At the onset of last week, my initial assignment involved implementing a temporary item filter functionality within a specific entity section of the application. This entailed making minor adjustments to the view model and slightly modifying the context. Following the implementation, I rigorously tested the filtration process to ensure flawless functionality and accurate data transmission. Subsequently, I undertook another task to incorporate a progress dialog bar in a similar part of the application. Although this task required minimal modifications, I conducted thorough unit tests to identify and address any potential oversights. During testing, I discovered some test failures, which traced back to the omission of mock services necessary after the implementation of SignalR.
Upon Mr. Peter’s review of my work, it became apparent that I had misunderstood the assigned task. It turns out that I was instructed to create an additional button instead of implementing another filter. Upon completing the task, I dedicated time to cleaning up my code, ensuring the removal of any unused or redundant segments. I then proceeded to inspect the user interface of the newly added feature.
Towards the conclusion of the week, several bugs were identified that necessitated fixing and code modifications. One notable issue involved a progress bar loading data, but when it exceeded 100 generations, a message indicating a batch size too large would appear. This particular issue will be my primary focus for the beginning of this week.
Focus on Customer Address Section
Last week I continued with the development of the customer page. Since I had already done the parts of the customer form before, I will continue to complete the customer form. Customer forms contain multiple data that needs to be inserted into, including name, contact number, remark, email, address lines, address options, address types, and detail contacts. This data is stored in one array per customer and some data will have multiple arrays. For example, customer 1 has multiple addresses, address options, fax, address contact and address type in one form. So I need to make the addresses work as an array within the form.
The solution to this problem is to use the “.map” function which allows the array to loop and display one at a time. When the array displays one by one, it is much easier for me to make the form. It is because not only can reduce the code required, but also easier to handle user input. The columns that the user input is the same, but only the array changes. For example, the first addresses will store data in “Addresses [1]”, while the second addresses will store data in “Addresses [2]”. The user can add as many addresses as they like when creating the customer data. I had tested the functions and the data is stored correctly in the array, which helps me to manage the data.
Besides, I also make a simple button that allows the user to click and add the empty address column. It will display like 2 address array per row, which will be different with the prototype I created before. In the prototype, I make the address array to be shown on the prompt page, but I found it difficult to develop because I already make the form prompt. To solve this problem, I decided to make the address column scrollable. This not only minimizes the number of clicks, but also keeps the length of the prompt page to a minimum. The prompt page will only have the exact same size and will not get longer and longer as you add more and more customer addresses.
Also, at the beginning of the coding, the address loop is in the same file as the other column. This makes the file very long. So I decided to put the functions related to addresses in separate files. However, the length of the file is still very long, I need to further minimize the length and move some functions such as address option, address type, address line and fax contact to new files. Finally, the length of the file has been reduced and the other file also has a shorter length. The files should be less complex and easier to debug. If one of the files has an error, it will be easier to identify and fix.
Finally, the form for the customer page is almost finished. I have managed to add multiple addresses to a single customer record. I will move on to using the API in the next few weeks. The API is a new genre for me and I may face difficulties in the following weeks.
Running the API in Postman
I began this week’s work by carrying on with the customer controller tests refactoring. I have combined the address and customer table data creation into a single variable. As a result, debugging and determining whether issues occur throughout the data generating process will become simpler for other users. In addition, it will be simpler for other users to add new customers or addresses for existing customers. Finally, the code will become more comprehensible by altering the customer and address table’s data creation structure.
After modifying the data seeding on the customer controller tests, Mr. Peter has informed me to do a new task, which is to do the query for items. The items will have the query feature of get the item list by name in pagination, get the item list with the filters, and get the item details. The item query will be different from the query for the customer, since the item will be a query from MongoDB. MongoDB is a cross-platform, source-available document-oriented database system. categorized as a database software using NoSQL. Since this is new to me, I’m still learning how to query from MongoDB.
Moreover, Mr. Peter has also given me another task, which is to test my API by using the Postman app. Postman is an API platform for building and using APIs. Postman makes the entire API lifecycle easier to understand and facilitates teamwork, enabling us to produce better APIs more quickly. In order to use the API document in the frontend implementation, I must first create a subdirectory containing it. Subsequently, I must publish my API project and transfer the generated files into the user folder that I have set up in FileZilla. Subsequently, I will need to rebuild the docker file to ensure that everything goes as planned and attempt to use Postman to execute the API.
But, I encountered an issue when utilizing Postman to run the API: I am unable to connect to the database. I’ve attempted a variety of approaches to the issue, such as altering the connection string’s hostname and adding additional symbols. Still, none of the fixes I tried have been successful. So, Mr. Peter has advised me to add some log information in my project to find exactly what is the problem that led to the error of the API. I have tried to add the log information in the controller in the API project. The value of the connection string was exactly what I wanted but the problem still hasn’t been solved. I will try to solve the problem next week.
Continue Modifying Prototype
After receiving some advice from Mr. Peter last week, I’m continuing to modify the customer function this week. First off, I’ve made improvements to my test for creating and deleting commands from customers. This is accomplished by adding the addresses count. I have to make sure that the addresses that customers submit will be added to the address table when they are creating new customers. So, I must verify that the address table’s address count is accurate. I have added a new function in the repository project, which is to get the total number of addresses in the address table. Thus, I can use this function in the testing project to see if the created addresses have been added or not.
The validation for creating and updating client features has then been added by me. The customer and created addresses will be verified as legitimate by further validation. Thus, I have verified the customer’s email address and phone number. The customer must input a phone number that is between 10 and 11 characters long. In the meanwhile, the client must confirm that the email address they supplied complies with the requirements for a valid email address format. In addition, I have developed validation that will determine whether the customer supplied any duplicate addresses. Furthermore, I have also developed validation to ensure that the customer would only choose one address.
Additionally, I modified the list query’s logic such that it now just displays each customer’s default address. In the meantime, the selected customer’s details will be displayed initially by the id query. A button next to the address box allows the customer to click and view all of the addresses they have created. Following the completion of the aforementioned enhancements, Mr. Peter has requested that a swagger be created for the customer feature. With the help of a user interface (UI) called Swagger, our users will be able to test out API calls right in their browsers. It will be possible for me to construct the swagger once I have appropriately configured everything.
Finally, after successfully building the UI, Mr. Peter reviewed my code. He realized that there are some improvements in the coding part that I can refactor it. I will try to refactor the code next week.
