Adding different metrics sections to the start page
In the initial version of the SUSI.AI Skill CMS we simply displayed all the skills present in the system in the form of cards. Once the skill analytics was incorporated into the CMS we got a bunch of skill statistics and thus we enhanced the start page by incorporating horizontally scrollable skill cards as per skill metrics like top rated skills, most used skills, skills which have received the most feedback etc. I worked on adding the skills with most feedback section and the section for the top games. This post will majorly deal with how the metrics sections are implemented on the start page and how any new metrics can be incorporated into the system and thus displayed on the CMS.
About the API
/cms/getSkillMetricsData.json?language=${language}
Sample API call:
https://api.susi.ai/cms/getSkillMetricsData.json?language=en
This will return a JSON which contains the skill data for all the metrics.
{ "accepted": true, "model": "general", "group": "All", "language": "en", "metrics": { "newest": [...], "rating": [...], ... } "message": "Success: Fetched skill data based on metrics", "session": {"identity": { "type": "host", "name": "162.158.23.7_68cefd16", "anonymous": true }} }
All of the data for several metics comes from the metrics object of the response which in turn contains arrays of skill data for each metric.
CMS Implementation
Once the BrowseSkill component is mounted we make an API call to the server to fetch all the data and save it to the component state, this data is then fed to the ScrollCardList component as props and the scroll component is rendered with appropriate data for different metrics.
loadMetricsSkills = () => { let url; url = urls.API_URL + '/cms/getSkillMetricsData.json?language=' + this.state.languageValue; let self = this; $.ajax({ url: url, dataType: 'jsonp', jsonp: 'callback', crossDomain: true, success: function(data) { self.setState({ skillsLoaded: true, staffPicksSkills: data.metrics.staffPicks, topRatedSkills: data.metrics.rating, topUsedSkills: data.metrics.usage, latestUpdatedSkills: data.metrics.latest, newestSkills: data.metrics.newest, topFeedbackSkills: data.metrics.feedback, topGames: data.metrics['Games, Trivia and Accessories'], }); }, error: function(e) { console.log('Error while fetching skills based on top metrics', e); return self.loadMetricsSkills(); }, }); };
We are using a single component for skill metrics and skill listing which show up on applying any filter or visiting any category. Thus we think of a condition when the skill metrics are to be displayed and conditionally render the metrics section depending on the condition.
So the metrics section shows up only when we have not visited any category or language page, there’s no search query in the search bar, there’s no rating refine filter applied and no time filter applied.
let metricsHidden = this.props.routeType || this.state.searchQuery.length > 0 || this.state.ratingRefine || this.state.timeFilter;
Depending on the section you want to display, pass appropriate data as props to the SkillCardScrollList component, say we want to display the section with most feedback
{this.state.topFeedbackSkills.length && !metricsHidden ? ( <div style={metricsContainerStyle}> <div style={styles.metricsHeader} className="metrics-header" > <h4> {'"SUSI, what are the skills with most feedback?"'} </h4> </div> {/* Scroll Id must be unique for all instances of SkillCardList*/} {!this.props.routeType && ( <SkillCardScrollList scrollId="topFeedback" skills={this.state.topFeedbackSkills} modelValue={this.state.modelValue} languageValue={this.state.languageValue} skillUrl={this.state.skillUrl} /> )} </div> ) : null}
So if there are skills preset in the topFeedbackSkills array which was saved in the state from the server initially and the condition to hide metrics is false we render the component and pass appropriate props for scrollId, skills data, language and model values and skill url.
In a similar way any metrics section can be implemented in the CMS, if the data is not present in the API, modify the endpoint to enclose the data you need, fetch data data from the server and just render it.
So I hope after reading through this you have a more clearer understanding about how the metrics sections are implemented on the CMS.
Resources
- Conditional rendering in React: https://reactjs.org/docs/conditional-rendering.html
- How to make AJAX requests in react: https://medium.com/@baphemot/how-to-make-ajax-requests-in-react-a6a52bb5a8b1