Ember Dashboard Components Pattern


#1

I’m building a dashboard in Ember that currently has five “widgets”. Each of these widgets is built as a component, and corresponds to a metric received from the API. At the moment, I’ve hacked together these components by making AJAX requests on didInsertElement, which I know is a Terrible Idea™, so I’m looking to recreate them using best practices.

Here’s an example of one of the widgets. It displays the number of overdue items.

import Ember from 'ember';
import API from '../utils/api';

export default Ember.Component.extend({
  items: 0,
  panelColor: function(){
    if (this.get('items') === 0) {
      return 'panel-green';
    } else if (this.get('items') < 25) {
      return 'panel-yellow';
    } else {
      return 'panel-red';
    }
  }.property('items'),
  didInsertElement: function(){
    var component = this;
    API.find('reports/overdue-items').then(function(response){
      component.set('items', response.overdue_items);
    });
  }
});

and the template:

{{#link-to 'overdue-items'}}
<div {{bind-attr class=":panel panelColor"}}>
  <div class="panel-heading">
    <div class="row">
      <div class="col-xs-3">
        <i class="fa fa-clock-o fa-5x"></i>
      </div>
      <div class="col-xs-9 text-right">
        <div class="huge">{{items}}</div>
        <div>Overdue Items</div>
      </div>
    </div>
  </div>
</div>
{{/link-to}}

Basically, the component gets a number from the API representing the number of overdue items and then renders the panel in one of three colors, based on how low the metric is.

My current plan is to move the AJAX call into a reporting service that returns the metrics needed for the component and render it like this:

{{max-overdue items=reportingService.maxOverdue}}

Where I seem to be getting confused is where does the logic that determines the panel’s color live? Should I put that into the app/components/maxOverdue.js file? Or should the reporting service return both the number of overdue items and what color the panel should be? My issue with the latter option is that the reporting service is now determining display logic as opposed to just providing data. The compromise I’ve come up with is leaving the panelColor property in maxOverdue.js, but I’m not sure if this is the best way to accomplish this.

Finally, if I’m going about this all wrong, please let me know!