holy moly

pangratz prattles

GitHub Dashboard #9

Goal of this iteration: Show a single repository

To show a single repository, I added more attributes to the Dashboard.Repository model.

A specific repository shall be accessible via the route /:username/:repository. Therefore, I updated the router so the user route now contains 2 sub-routes index and repository. Inside the index route everything is setup as before: get the watched repositories for the user and connect the outlet. The repository route gets the repository which is specified in the url and connects the outlet. That simple. Because both sub-routes need to know what the ‘current’ username is, I’ve created a Dashboard.UserController which currently just holds the username. The value of this property is set in the connectOutlets of the user route. The updated user route now looks like this:

app/lib/router.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
user: Ember.Route.extend({
  route: '/:username',
  connectOutlets: function(router, context) {
    router.set('userController.username', context.username);
  },

  index: Ember.Route.extend({
    route: '/',
    connectOutlets: function(router) {
      var username = router.get('userController.username');
      var store = router.get('store');

      // get watched repositories for given username
      var watchedRepositories = store.findQuery(Dashboard.Repository, {
        username: username,
        type: 'watched'
      });

      // set watched repositories on repositoriesController
      router.set('repositoriesController.content', watchedRepositories);

      // show repositories
      router.get('applicationController').connectOutlet('repositories');
    }
  }),

  repository: Ember.Route.extend({
    route: '/:repository',
    connectOutlets: function(router, context) {
      var username = router.get('userController.username');
      var repoName = context.repository;

      // fetch repo for current user
      // id of the repository is username/repoName
      var repo = router.get('store').find(Dashboard.Repository, '%@/%@'.fmt(username, repoName));
      router.set('repositoryController.content', repo);

      // show repository
      router.get('applicationController').connectOutlet('repository');
    }
  })
})

To get a specific repository I implemented the find method on GitHubAdapter as follows:

app/lib/github_adapter.js
1
2
3
4
5
6
7
find: function(store, type, id) {
  if (Dashboard.Repository.detect(type)) {
    this.ajax('/repos/%@'.fmt(id), function(data) {
      store.load(type, id, data);
    });
  }
}

To show watched repositories of a user, I added the action showUser to the router. The action showRepository handles the case when a specific repository shall be shown. These actions are declared inside the user route:

app/lib/router.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
showUser: function(router, evt) {
  var username;
  var context = evt.context;

  // context is a Dashboard.RepositoryController if this action
  // is called from repository template --> this needs to be fixed
  if (Dashboard.RepositoryController.detectInstance(context)) {
    username = context.get('owner.login');
  } else {
    username = context;
  }

  router.transitionTo('user.index', {
    username: username
  });
},

showRepository: function(router, evt) {
  // context is the full_name of a repository: username/repository
  var split = evt.context.split('/'),
      username = split[0],
      repository = split[1];

  router.transitionTo('user.repository', {username: username}, {repository: repository});
}

As a final step, I adapted the repositories template so it’s possible to show a specific user or repository:

lib/templates/repositories.handlebars (repositories.handlebars) download
1
2
3
4
5
6
7
8
<div class="row">Watched repositories:</div>
<div class="row" >
    {{#each repository in controller}}
        <a {{action showUser context="repository.owner.login"}} >{{repository.owner.login}}</a> / <a {{action showRepository context="repository.full_name"}} >{{repository.name}}</a>
        {{repository.description}}
        <dl class="dl-horizontal">
    {{/each}}
</div>

The newly created template for the repository looks like this:

lib/templates/repository.handlebars (repository.handlebars) download
1
2
3
4
5
6
7
8
9
<div class="well" >
    <a {{action showUser }} >{{owner.login}}</a> / {{name}} – <a {{bindAttr href="html_url"}}>show@GitHub</a>
    <dl class="dl-horizontal">
    {{description}}
    <dl class="dl-horizontal">
    <span class="badge" title="watchers" ><i class="icon-eye-open" ></i> {{watchers}}</span>
    <span class="badge" title="forks" ><i class="icon-heart" ></i> {{forks}}</span>
    <span class="badge" ><i class="icon-tag" ></i> {{language}}</span>
</div>

Roundup

Now we can show the watched repositories of an user and also show a specific repository. Dashboard is growing steadily. I like.

The result of this post’s changes are available at tag v0.0.9 (changes). As always, the result is deployed at code418.com/dashboard.

Comments