Displaying skill rating for each skill on skill page of SUSI SKILL CMS

SUSI exhibits several skills which are managed by the SUSI Skill CMS, it essentially is a client which allows users to create/update skills conveniently since for each skill it is important to have the functionality of rating system so developers can get to know which skills are performing better than the rest and consequently improve them, thus a skill rating system which allows the users to give positive or negative feedback for each skill is implemented on the server. Fetching skill_rating from the server Fetch skill data for which ratings are to be displayed through ajax calls API Endpoint - /cms/getSkillMetadata.json?… Parse the received metadata object to get positive and negative ratings for that skill if(skillData.skill_rating) { let positive_rating = skillData.skill_rating.positive; let negative_rating = skillData.skill_rating.negative; } Sample API response { "skill_metadata": { "model": "general", "group": "Knowledge", "language": "en", "developer_privacy_policy": null, "descriptions": "Want to know about fossasia, just ask susi to tell that, Susi tells about the SUSI.AI creators", "image": "images/creator_info.png", "author": "madhav rathi", "author_url": "https://github.com/madhavrathi", "author_email": null, "skill_name": "Creator Info", "terms_of_use": null, "dynamic_content": false, "examples": [ "Who created you?", "what is fossasia?" ], "skill_rating": { "negative": "0", "positive": "0", "stars": { "one_star": 0, "four_star": 0, "five_star": 0, "total_star": 0, "three_star": 0, "avg_star": 0, "two_star": 0 }, "feedback_count": 0 }, "creationTime": "2018-03-17T16:38:29Z", "lastAccessTime": "2018-06-15T15:51:50Z", "lastModifiedTime": "2018-03-17T16:38:29Z" }, "accepted": true, "message": "Success: Fetched Skill's Metadata", "session": {"identity": { "type": "host", "name": "162.158.166.37_d80fb5c9", "anonymous": true }} } Set the react state of the component to store positive and negative rating. this.setState({ positive_rating, negative_rating }) Use react-icons to fetch like and dislike icon components from font-awesome. npm i -S react-icons Import the corresponding icons in the SkillPage component import { FaThumbsOUp, FaThumbsODown } from 'react-icons/lib/fa/' Display the rating count along with their icons <div className="rating"> <div className="positive"> <FaThumbsOUp /> {this.state.positive_rating} </div> <div className="negative"> <FaThumbsODown /> {this.state.negative_rating} </div> </div> Example References react-icons npm package Blog on icons as react components - https://medium.com/@david.gilbertson/icons-as-react-components-de3e33cb8792

Continue ReadingDisplaying skill rating for each skill on skill page of SUSI SKILL CMS

SUSI AI 5 Star Skill Rating System

For making a system more reliable and robust, continuous evaluation is quite important. So is in case of SUSI AI. User feedback is important to improve SUSI skills and create new ones. Previously we had only thumbs up / thumbs down as a feedback method, from the susi chat client. But now a 5 star rating system has been added to the SUSI Skill CMS so that users can rate a skill there. Before the implementation of API  let’s look how data is stored in SUSI AI Susi_server uses DAO in which skill rating is stored as JSONTray. The server side implementation A new java class has been created for the API, FiveStarRateSkillService.java. public class FiveStarRateSkillService extends AbstractAPIHandler implements APIHandler { private static final long serialVersionUID =7947060716231250102L; @Override public BaseUserRole getMinimalBaseUserRole() { return BaseUserRole.USER; } @Override public JSONObject getDefaultPermissions(BaseUserRole baseUserRole) { return null; } @Override public String getAPIPath() { return "/cms/rateSkill.json"; } ... } The getMinimalBaseRole method tells the minimum User role required to access this servlet it can also be ADMIN, USER or ANONYMOUS. In our case it is USER. A user needs to be logged in to rate a skill on a scale of 1-5 stars.  The API runs at “/cms/fiveStarRateSkill.json” endpoint. Next, create serviceImpl method in the above class to handle the request from the client and respond to it. 1. Fetch the required query parameters and store them in variables. They include skill model, group, language, skill name and starts that the user has given in the rating. String skill_name = call.get("skill", null); String skill_stars = call.get("stars", null); 2. Then check if the skill exists. If not them throw an exception. Otherwise, increment the count of the corresponding rating. The rating object has keys as one_star, two_star, three_star, four_star and five_star that has the count of that star rating.        if (skill_stars.equals("1")) { skillName.put("one_star", skillName.getInt("one_star") + 1 + ""); } else if (skill_stars.equals("2")) { skillName.put("two_star", skillName.getInt("two_star") + 1 + ""); } else if (skill_stars.equals("3")) { skillName.put("three_star", skillName.getInt("three_star") + 1 + ""); } else if (skill_stars.equals("4")) { skillName.put("four_star", skillName.getInt("four_star") + 1 + ""); } else if (skill_stars.equals("5")) { skillName.put("five_star", skillName.getInt("five_star") + 1 + ""); } 3. Re-calculate the total rating done on that skill and its average rating and update the object. If the skill has not been already rated then create a new rating object and initialize it with the 0 star counts. public JSONObject createRatingObject(String skill_stars) { JSONObject skillName = new JSONObject(); JSONObject skillStars = new JSONObject(); skillStars.put("one_star", 0); skillStars.put("two_star", 0); skillStars.put("three_star", 0); skillStars.put("four_star", 0); skillStars.put("five_star", 0); skillStars.put("avg_star", 0); skillStars.put("total_star", 0); skillName.put("stars", skillStars); } The complete FiveStarRateSkillService.java is available here : - https://github.com/fossasia/susi_server/blob/development/src/ai/susi/server/api/cms/FiveStarRateSkillService.java Rating a skill Sample endpoint https://api.susi.ai/cms/fiveStarRateSkill.json?model=general&group=Knowledge&language=en&skill=aboutsusi&stars=3&callback=p&_=1526813916145 This gives 3 star rating to the “aboutsusi” skill. Parameters Model Group Language Skill Stars Response { "ratings": { "one_star": 0, "four_star": 0, "five_star": 1, "total_star": 1, "three_star": 0, "avg_star": 5, "two_star": 0 }, "session": {"identity": { "type": "email", "name": "1anuppanwar@gmail.com", "anonymous": false }}, "accepted": true, "message": "Skill ratings updated" } Getting the stats…

Continue ReadingSUSI AI 5 Star Skill Rating System

Dynamic Ticket Analysis UI using Data Binding in Open Event Android Orga App

Any event manager application has the responsibility to show the analytics about the event to the organiser and in Open Event Android Orga App (Github Repo), we wanted to achieve a way to display the analytics of total and sold tickets with the data present to us. To analyse, we have a list of tickets, which are divided into 3 categories: Free Paid Donation Our goal was to show information about total tickets and the amount of sold tickets per category. This blog will focus on the dynamic UI creation for the ticket analysis component of the Event Details Dashboard using Android Layout Data Binding. By using Data Binding, we not only reduced the amount of Java Boilerplate code we would have to write, but also accomplished UI reuse in just XML which wouldn’t have been possible without it. You’ll see in a moment what I mean. Properties So first, we’d need to define some properties which will be bound in the UI. These properties are declared in the Event model and their type is ObservableLong provided by the Android DataBinding package. The reason why we are using these instead of primitives is because these fields being Observable, will update the UI as soon as they are updated, without requiring the programmer to set the View Property at all. There are six fields, 3 for total tickets of each type and 3 for sold tickets public final ObservableLong freeTickets = new ObservableLong(); public final ObservableLong paidTickets = new ObservableLong(); public final ObservableLong donationTickets = new ObservableLong(); public final ObservableLong soldFreeTickets = new ObservableLong(); public final ObservableLong soldPaidTickets = new ObservableLong(); public final ObservableLong soldDonationTickets = new ObservableLong(); Some more advantages we get from using these are the batch view update and the use of computed properties in UI. Imagine having a TextView display the amount of free tickets and a progress bar showing the percentage of free tickets sold. Traditionally, you’d have to set the text and compute the percentage and set the progress bar as the data changes, whereas you can just use the fields in layout as is in both TextView and ProgressBar with the computations required and they’ll work in harmony. We have leveraged this feature to show the analytics component of tickets with a Ticket Type Circular Progress Bar Sold Tickets Total Tickets All using the XML layout and databinding Ticket Component For each ticket component, we have 4 variables, namely Ticket Type Name Total Amount Completed Amount (Sold Tickets) Color First 3 are fairly self explanatory, the color attribute we used in our component needs a little bit of description. We decided to give each ticket category its own color for circular progress bar for aesthetics. So, we need each component to have its own color attribute too. But this is not a normal android color ID or a hex. We needed 2 variants of the same color to show in the circular progress to discern the total and completed part. As we are using…

Continue ReadingDynamic Ticket Analysis UI using Data Binding in Open Event Android Orga App