Cards and Columns;
A Kanban Process for Bugzilla
Derek Ries
WebDev Intern - Summer 2013
Overview
- One main project this summer, Kanbanzilla
- What the project is
- What it's for, with some background info
- How it was built
Kanbanzilla
- An internal tool that provides a Kanban board to triage bugs in Bugzilla.
- Integrated so that changes made to the board are reflected in Bugzilla and vice versa.
What is Kanban?
- Scheduling system for JIT Production
- Work-in-progress limited pull system
- Set of steps in the development process
- Work is pulled into subsequent steps
- Doesn't prescribe doing anything radically different
Kanban Origins
- Roughly translates into "signboard" or "signal card" in Japanese.
- Originally a scheduling system developed by Taiichi Ohno for Toyota factories.
Building Cars or software?
- Obviously a different process
- But the underlying idea of managing a production pipeline is the same
Core Principles
- Visualize
- Limit WIP
- Manage Flow
- Make Policies Explicit
- Implement Feedback Loops
- Improve Collaboratively, evolve experimentally
What about Bugzilla?
- Bug Tracking System
- Need something done? File a bug.
- Lots of bugs to manage and we need to resolve them
Problem?
Well, there aren't many kanban applications out there.
- yodiz
- kanbanize
- kanban-tool
- trello
- leankit
- targetprocess
- breeze
- swift-kanban
- GreenHopper / Jira
- Kanbannery
- I Lied, there's a lot
Real Problem
- Using any one of these tools requires updating data in two places and keeping them in sync
- Change the board, go change Bugzilla.
- Change Bugzilla, go change the board.
- Don't like that, we want a board that just works.
Back to Kanbanzilla
- On its' own, Bugzilla maps fairly well to a Kanban process.
- Boards could be composed of existing Bugzilla components
- Statuses could become the columns on the board.
- Unconfirmed, New, Assigned, Ready, Resolved, Verified, Reopened
- But there were a few intermediary steps that were desired.
Kanbanzilla Columns
- Map to one or more statuses
- Or have no status mapping and instead become a "virtual" column that was backed by some whiteboard data
- Verified serves as an archive of sorts
Building Kanbanzilla
- Initially intended as an entirely client-side application.
- Built with Angularjs and Flask
The Server
- Thin layer on top of Bugzilla REST API
- Creating and sharing boards
- Auth
username=me@mozilla.com&password=lolnope
userid=1234&cookie=mGjlksad94
Why Use Angular?
- Most experienced with
- Doing things the angular way produces an application that is flexible, and easily reasoned about.
- Support for testing
- Community
Angular Features
- Two-way data-binding.
- Directives (web components)
- Filters
- Services
- Dependency Injection
- Extends HTML
The Angular Way
- Not jQuery
- Instead of reaching into the DOM to make the UI reflect the model, focus on manipulating data, and let data-binding and directives render that data for you.
- When we do need to touch the DOM, this can be encapsulated as a directive, a web component of sorts.
Directives
angular.module('myApp')
.directive('calendar', function () {
return {
restrict: 'E', // or 'A', or 'C'
scope: {},
templateUrl: 'views/calendar.tpl.html',
link: function (scope, elem, attrs) {
// directive functionality
}
}
});
Make your HTML an app-specific DSL
views/board.html
<input type="text"
id="board-search"
class="input-medium search-query"
placeholder="Search..."
grow-when-clicked="300"
ng-model="query">
<div class="board-dropzone unselectable" auto-fill-height>
<div class="board-dropzone-inner" fancy-scroll-horizontally>
<kbcolumn ng-repeat="column in board.columns"
display-title="{{column.name}}"
ng-model="column"
sort-options="sortableOptions"
query="query">
</kbcolumn>
</div>
</div>
Some Things I've Learned About Angular After Making Several Applications
- Performance
- Use promises for a lot of features in angular
- Truly Re-usable Components
Performance
- Angular makes it really easy to start getting things working
- BUT, larger apps require some consideration when using those "easy" features.
Throttling / Debouncing
<input ng-model="query">
<ul>
<li ng-repeat="item in items | filter:query"></li>
</ul>
- Frequent model changes and re-rendering.
- If we have a lot of data, then typing gets sluggish.
- Probably want to type more than one character anyway.
Debouncing
- != Throttling
- Coalesce several signals into one
- Can ignore the signals until some completion delay has elapsed, then trigger the update/signal
throttling
Debouncing As A Directive
<input ng-model="query" debounce-model-update="400">
"Why does ng-repeat suck?'
- Stop trying to render all 10,000 items at once
- Not just a performance problem, also a UX problem
- Try pagination or infinite scrolling to render only a subset of the collection at any one time.
Take Advantage of Promises
getDataForUser('me', function (err, result) { ... });
var dataPromise = getDataForUser('me');
- Treat these promises as objects now, to pass around, and aggregate
- Angular comes with a lot of functionality for promises.
- Route resolve property
- Interceptors
Route Resolve Property
Typical Before
App Routes
$routeProvider
.when('/board/:id', {
templateUrl: 'views/board.html',
controller: 'BoardCtrl'
});
BoardCtrl
angular.module('myApp')
.controller('BoardCtrl',
['Board','$routeParams', function (Board, $routeParams) {
Board.getBoardData($routeParams.id).success(function (result) {
$scope.boardData = result.data
});
}]);
Route Resolve Property
After
$routeProvider
.when('/board/:id', {
templateUrl: 'views/board.html',
controller: 'BoardCtrl',
resolve: {
board: ['Boards', '$route', function (Boards, $route) {
Boards.get($route.current.params.id);
})
}
angular.module('myApp')
.controller('BoardCtrl', ['board', function (board) {
// board is injected into the controller as the result
// of the resolved promise
}]);
Current Status
- Have 1.5 weeks left in my internship
- Kanbanzilla is being deployed
- Optimizations like the debounce stuff not included yet.
Future Work
- Upgrade to Angular 1.2
- Animations
- Simplify Code and some perf stuff
- UI Changes
- Sort order of bugs
- Custom Columns
- Apply filters to queries when creating boards, more than just component selection
Thanks
Christopher Lonnen
Peter Bengtsson
Jake Maul