Initial kanban code.
parent
b172b07ed9
commit
a8f9bd0303
|
@ -26,6 +26,7 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide) ->
|
||||||
$routeProvider.when("/project/:pslug/backlog", {templateUrl: "/partials/backlog.html"})
|
$routeProvider.when("/project/:pslug/backlog", {templateUrl: "/partials/backlog.html"})
|
||||||
$routeProvider.when("/project/:pslug/taskboard/:id", {templateUrl: "/partials/taskboard.html"})
|
$routeProvider.when("/project/:pslug/taskboard/:id", {templateUrl: "/partials/taskboard.html"})
|
||||||
$routeProvider.when("/project/:pslug/search", {templateUrl: "/partials/search.html"})
|
$routeProvider.when("/project/:pslug/search", {templateUrl: "/partials/search.html"})
|
||||||
|
$routeProvider.when("/project/:pslug/kanban", {templateUrl: "/partials/kanban.html"})
|
||||||
|
|
||||||
# User stories
|
# User stories
|
||||||
$routeProvider.when("/project/:pslug/us/:usref",
|
$routeProvider.when("/project/:pslug/us/:usref",
|
||||||
|
@ -121,6 +122,7 @@ modules = [
|
||||||
# Specific Modules
|
# Specific Modules
|
||||||
"taigaBacklog",
|
"taigaBacklog",
|
||||||
"taigaTaskboard",
|
"taigaTaskboard",
|
||||||
|
"taigaKanban"
|
||||||
"taigaIssues",
|
"taigaIssues",
|
||||||
"taigaUserStories",
|
"taigaUserStories",
|
||||||
"taigaTasks",
|
"taigaTasks",
|
||||||
|
|
|
@ -54,6 +54,7 @@ urls = {
|
||||||
"project": "/project/:project",
|
"project": "/project/:project",
|
||||||
"project-backlog": "/project/:project/backlog",
|
"project-backlog": "/project/:project/backlog",
|
||||||
"project-taskboard": "/project/:project/taskboard/:sprint",
|
"project-taskboard": "/project/:project/taskboard/:sprint",
|
||||||
|
"project-kanban": "/project/:project/kanban",
|
||||||
"project-issues": "/project/:project/issues",
|
"project-issues": "/project/:project/issues",
|
||||||
"project-search": "/project/:project/search",
|
"project-search": "/project/:project/search",
|
||||||
"project-issues-detail": "/project/:project/issues/:ref",
|
"project-issues-detail": "/project/:project/issues/:ref",
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
||||||
|
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
|
||||||
|
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# File: modules/kanban.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
module = angular.module("taigaKanban", [])
|
|
@ -0,0 +1,273 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
||||||
|
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
|
||||||
|
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# File: modules/kanban/main.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
taiga = @.taiga
|
||||||
|
|
||||||
|
mixOf = @.taiga.mixOf
|
||||||
|
toggleText = @.taiga.toggleText
|
||||||
|
scopeDefer = @.taiga.scopeDefer
|
||||||
|
bindOnce = @.taiga.bindOnce
|
||||||
|
groupBy = @.taiga.groupBy
|
||||||
|
|
||||||
|
module = angular.module("taigaKanban")
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## Kanban Controller
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.FiltersMixin)
|
||||||
|
@.$inject = [
|
||||||
|
"$scope",
|
||||||
|
"$rootScope",
|
||||||
|
"$tgRepo",
|
||||||
|
"$tgConfirm",
|
||||||
|
"$tgResources",
|
||||||
|
"$routeParams",
|
||||||
|
"$q",
|
||||||
|
"$tgLocation"
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location) ->
|
||||||
|
_.bindAll(@)
|
||||||
|
|
||||||
|
@scope.sectionName = "Kanban"
|
||||||
|
|
||||||
|
promise = @.loadInitialData()
|
||||||
|
promise.then null, =>
|
||||||
|
console.log "FAIL"
|
||||||
|
|
||||||
|
# @scope.$on("usform:bulk:success", @.loadUserstories)
|
||||||
|
# @scope.$on("sprintform:create:success", @.loadSprints)
|
||||||
|
# @scope.$on("sprintform:create:success", @.loadProjectStats)
|
||||||
|
# @scope.$on("sprintform:remove:success", @.loadSprints)
|
||||||
|
# @scope.$on("sprintform:remove:success", @.loadProjectStats)
|
||||||
|
# @scope.$on("usform:new:success", @.loadUserstories)
|
||||||
|
# @scope.$on("usform:edit:success", @.loadUserstories)
|
||||||
|
# @scope.$on("sprint:us:move", @.moveUs)
|
||||||
|
# @scope.$on("sprint:us:moved", @.loadSprints)
|
||||||
|
# @scope.$on("sprint:us:moved", @.loadProjectStats)
|
||||||
|
|
||||||
|
loadProjectStats: ->
|
||||||
|
return @rs.projects.stats(@scope.projectId).then (stats) =>
|
||||||
|
@scope.stats = stats
|
||||||
|
completedPercentage = Math.round(100 * stats.closed_points / stats.total_points)
|
||||||
|
@scope.stats.completedPercentage = "#{completedPercentage}%"
|
||||||
|
return stats
|
||||||
|
|
||||||
|
loadUserstories: ->
|
||||||
|
return @rs.userstories.listUnassigned(@scope.projectId).then (userstories) =>
|
||||||
|
@scope.userstories = userstories
|
||||||
|
|
||||||
|
@scope.usByStatus = _.groupBy(userstories, "status")
|
||||||
|
|
||||||
|
for status in @scope.usStatusList
|
||||||
|
if not @scope.usByStatus[status.id]?
|
||||||
|
@scope.usByStatus[status.id] = []
|
||||||
|
|
||||||
|
# The broadcast must be executed when the DOM has been fully reloaded.
|
||||||
|
# We can't assure when this exactly happens so we need a defer
|
||||||
|
scopeDefer @scope, =>
|
||||||
|
@scope.$broadcast("userstories:loaded")
|
||||||
|
|
||||||
|
return userstories
|
||||||
|
|
||||||
|
loadKanban: ->
|
||||||
|
return @q.all([
|
||||||
|
@.loadProjectStats(),
|
||||||
|
@.loadUserstories()
|
||||||
|
])
|
||||||
|
|
||||||
|
loadProject: ->
|
||||||
|
return @rs.projects.get(@scope.projectId).then (project) =>
|
||||||
|
@scope.project = project
|
||||||
|
@scope.points = _.sortBy(project.points, "order")
|
||||||
|
@scope.pointsById = groupBy(project.points, (x) -> x.id)
|
||||||
|
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id)
|
||||||
|
@scope.usStatusList = _.sortBy(project.us_statuses, "id")
|
||||||
|
return project
|
||||||
|
|
||||||
|
loadInitialData: ->
|
||||||
|
# Resolve project slug
|
||||||
|
promise = @repo.resolve({pslug: @params.pslug}).then (data) =>
|
||||||
|
@scope.projectId = data.project
|
||||||
|
return data
|
||||||
|
|
||||||
|
return promise.then(=> @.loadProject())
|
||||||
|
.then(=> @.loadUsersAndRoles())
|
||||||
|
.then(=> @.loadKanban())
|
||||||
|
|
||||||
|
prepareBulkUpdateData: (uses) ->
|
||||||
|
return _.map(uses, (x) -> [x.id, x.order])
|
||||||
|
|
||||||
|
resortUserStories: (uses) ->
|
||||||
|
items = []
|
||||||
|
for item, index in uses
|
||||||
|
item.order = index
|
||||||
|
if item.isModified()
|
||||||
|
items.push(item)
|
||||||
|
|
||||||
|
return items
|
||||||
|
|
||||||
|
moveUs: (ctx, us, newUsIndex, newSprintId) ->
|
||||||
|
oldSprintId = us.milestone
|
||||||
|
|
||||||
|
# In the same sprint or in the backlog
|
||||||
|
if newSprintId == oldSprintId
|
||||||
|
items = null
|
||||||
|
userstories = null
|
||||||
|
|
||||||
|
if newSprintId == null
|
||||||
|
userstories = @scope.userstories
|
||||||
|
else
|
||||||
|
userstories = @scope.sprintsById[newSprintId].user_stories
|
||||||
|
|
||||||
|
@scope.$apply ->
|
||||||
|
r = userstories.indexOf(us)
|
||||||
|
userstories.splice(r, 1)
|
||||||
|
userstories.splice(newUsIndex, 0, us)
|
||||||
|
|
||||||
|
# Rehash userstories order field
|
||||||
|
items = @.resortUserStories(userstories)
|
||||||
|
data = @.prepareBulkUpdateData(items)
|
||||||
|
|
||||||
|
# Persist in bulk all affected
|
||||||
|
# userstories with order change
|
||||||
|
promise = @rs.userstories.bulkUpdateOrder(us.project, data).then =>
|
||||||
|
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
|
||||||
|
|
||||||
|
promise.then null, ->
|
||||||
|
console.log "FAIL"
|
||||||
|
|
||||||
|
return promise
|
||||||
|
|
||||||
|
# From sprint to backlog
|
||||||
|
if newSprintId == null
|
||||||
|
us.milestone = null
|
||||||
|
|
||||||
|
@scope.$apply =>
|
||||||
|
# Add new us to backlog userstories list
|
||||||
|
@scope.userstories.splice(newUsIndex, 0, us)
|
||||||
|
@scope.visibleUserstories.splice(newUsIndex, 0, us)
|
||||||
|
|
||||||
|
# Execute the prefiltering of user stories
|
||||||
|
@.filterVisibleUserstories()
|
||||||
|
|
||||||
|
# Remove the us from the sprint list.
|
||||||
|
sprint = @scope.sprintsById[oldSprintId]
|
||||||
|
r = sprint.user_stories.indexOf(us)
|
||||||
|
sprint.user_stories.splice(r, 1)
|
||||||
|
|
||||||
|
# Persist the milestone change of userstory
|
||||||
|
promise = @repo.save(us)
|
||||||
|
|
||||||
|
# Rehash userstories order field
|
||||||
|
# and persist in bulk all changes.
|
||||||
|
promise = promise.then =>
|
||||||
|
items = @.resortUserStories(@scope.userstories)
|
||||||
|
data = @.prepareBulkUpdateData(items)
|
||||||
|
promise = @rs.userstories.bulkUpdateOrder(us.project, data).then =>
|
||||||
|
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
|
||||||
|
|
||||||
|
promise.then null, ->
|
||||||
|
# TODO
|
||||||
|
console.log "FAIL"
|
||||||
|
|
||||||
|
return promise
|
||||||
|
|
||||||
|
# From backlog to sprint
|
||||||
|
newSprint = @scope.sprintsById[newSprintId]
|
||||||
|
if us.milestone == null
|
||||||
|
us.milestone = newSprintId
|
||||||
|
|
||||||
|
@scope.$apply =>
|
||||||
|
# Add moving us to sprint user stories list
|
||||||
|
newSprint.user_stories.splice(newUsIndex, 0, us)
|
||||||
|
|
||||||
|
# Remove moving us from backlog userstories lists.
|
||||||
|
r = @scope.visibleUserstories.indexOf(us)
|
||||||
|
@scope.visibleUserstories.splice(r, 1)
|
||||||
|
r = @scope.userstories.indexOf(us)
|
||||||
|
@scope.userstories.splice(r, 1)
|
||||||
|
|
||||||
|
# From sprint to sprint
|
||||||
|
else
|
||||||
|
us.milestone = newSprintId
|
||||||
|
|
||||||
|
@scope.$apply =>
|
||||||
|
# Add new us to backlog userstories list
|
||||||
|
newSprint.user_stories.splice(newUsIndex, 0, us)
|
||||||
|
|
||||||
|
# Remove the us from the sprint list.
|
||||||
|
oldSprint = @scope.sprintsById[oldSprintId]
|
||||||
|
r = oldSprint.user_stories.indexOf(us)
|
||||||
|
oldSprint.user_stories.splice(r, 1)
|
||||||
|
|
||||||
|
# Persist the milestone change of userstory
|
||||||
|
promise = @repo.save(us)
|
||||||
|
|
||||||
|
# Rehash userstories order field
|
||||||
|
# and persist in bulk all changes.
|
||||||
|
promise = promise.then =>
|
||||||
|
items = @.resortUserStories(newSprint.user_stories)
|
||||||
|
data = @.prepareBulkUpdateData(items)
|
||||||
|
promise = @rs.userstories.bulkUpdateOrder(us.project, data).then =>
|
||||||
|
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
|
||||||
|
|
||||||
|
promise.then null, ->
|
||||||
|
# TODO
|
||||||
|
console.log "FAIL"
|
||||||
|
|
||||||
|
return promise
|
||||||
|
|
||||||
|
## Template actions
|
||||||
|
# editUserStory: (us) ->
|
||||||
|
# @rootscope.$broadcast("usform:edit", us)
|
||||||
|
|
||||||
|
# deleteUserStory: (us) ->
|
||||||
|
# #TODO: i18n
|
||||||
|
# title = "Delete User Story"
|
||||||
|
# subtitle = us.subject
|
||||||
|
|
||||||
|
# @confirm.ask(title, subtitle).then =>
|
||||||
|
# # We modify the userstories in scope so the user doesn't see the removed US for a while
|
||||||
|
# @scope.userstories = _.without(@scope.userstories, us);
|
||||||
|
# @filterVisibleUserstories()
|
||||||
|
# @.repo.remove(us).then =>
|
||||||
|
# @.loadBacklog()
|
||||||
|
|
||||||
|
# addNewUs: (type) ->
|
||||||
|
# switch type
|
||||||
|
# when "standard" then @rootscope.$broadcast("usform:new")
|
||||||
|
# when "bulk" then @rootscope.$broadcast("usform:bulk")
|
||||||
|
|
||||||
|
|
||||||
|
module.controller("KanbanController", KanbanController)
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## Kanban Directive
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
KanbanDirective = ($repo, $rootscope) ->
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
return {link: link}
|
||||||
|
|
||||||
|
|
||||||
|
module.directive("tgKanban", ["$tgRepo", "$rootScope", KanbanDirective])
|
|
@ -0,0 +1,94 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
||||||
|
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
|
||||||
|
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# File: modules/kanban/sortable.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
taiga = @.taiga
|
||||||
|
|
||||||
|
mixOf = @.taiga.mixOf
|
||||||
|
toggleText = @.taiga.toggleText
|
||||||
|
scopeDefer = @.taiga.scopeDefer
|
||||||
|
bindOnce = @.taiga.bindOnce
|
||||||
|
groupBy = @.taiga.groupBy
|
||||||
|
|
||||||
|
module = angular.module("taigaKanban")
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## Sortable Directive
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
KanbanSortableDirective = ($repo, $rs, $rootscope) ->
|
||||||
|
|
||||||
|
#########################
|
||||||
|
## Drag & Drop Link
|
||||||
|
#########################
|
||||||
|
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
oldParentScope = null
|
||||||
|
newParentScope = null
|
||||||
|
itemEl = null
|
||||||
|
tdom = $el
|
||||||
|
|
||||||
|
deleteElement = (itemEl) ->
|
||||||
|
# Completelly remove item and its scope from dom
|
||||||
|
itemEl.scope().$destroy()
|
||||||
|
itemEl.off()
|
||||||
|
itemEl.remove()
|
||||||
|
|
||||||
|
tdom.sortable({
|
||||||
|
handle: ".icon-drag-h",
|
||||||
|
dropOnEmpty: true
|
||||||
|
connectWith: ".taskboard_task-playground"
|
||||||
|
revert: 400
|
||||||
|
})
|
||||||
|
|
||||||
|
tdom.on "sortstop", (event, ui) ->
|
||||||
|
# parentEl = ui.item.parent()
|
||||||
|
# itemEl = ui.item
|
||||||
|
# itemTask = itemEl.scope().task
|
||||||
|
# itemIndex = itemEl.index()
|
||||||
|
# newParentScope = parentEl.scope()
|
||||||
|
|
||||||
|
# oldUsId = if oldParentScope.us then oldParentScope.us.id else null
|
||||||
|
# oldStatusId = oldParentScope.st.id
|
||||||
|
# newUsId = if newParentScope.us then newParentScope.us.id else null
|
||||||
|
# newStatusId = newParentScope.st.id
|
||||||
|
|
||||||
|
# if newStatusId != oldStatusId or newUsId != oldUsId
|
||||||
|
# deleteElement(itemEl)
|
||||||
|
|
||||||
|
# $scope.$apply ->
|
||||||
|
# $rootscope.$broadcast("taskboard:task:move", itemTask, newUsId, newStatusId, itemIndex)
|
||||||
|
|
||||||
|
tdom.on "sortstart", (event, ui) ->
|
||||||
|
oldParentScope = ui.item.parent().scope()
|
||||||
|
|
||||||
|
$scope.$on "$destroy", ->
|
||||||
|
$el.off()
|
||||||
|
|
||||||
|
return {link: link}
|
||||||
|
|
||||||
|
|
||||||
|
module.directive("tgKanbanSortable", [
|
||||||
|
"$tgRepo",
|
||||||
|
"$tgResources",
|
||||||
|
"$rootScope",
|
||||||
|
KanbanSortableDirective
|
||||||
|
])
|
|
@ -82,7 +82,7 @@ ProjectMenuDirective = ($log, $compile, $rootscope) ->
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li id="nav-kanban">
|
<li id="nav-kanban">
|
||||||
<a href="" title="Kanban">
|
<a href="" title="Kanban" tg-nav="project-kanban:project=project.slug">
|
||||||
<span class="icon icon-kanban"></span><span class="item">Kanban</span>
|
<span class="icon icon-kanban"></span><span class="item">Kanban</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
extends layout
|
extends dummy-layout
|
||||||
|
|
||||||
block head
|
block head
|
||||||
title Taiga Project management web application with scrum in mind!
|
title Taiga Project management web application with scrum in mind!
|
||||||
|
|
||||||
block content
|
block content
|
||||||
div.wrapper
|
div.wrapper(tg-kanban, ng-controller="KanbanController as ctrl")
|
||||||
section.main.kanban
|
section.main.kanban
|
||||||
div.kanban-detail-header
|
div.kanban-detail-header
|
||||||
h1
|
h1
|
||||||
span ProjectName
|
span(tg-bo-html="project.name")
|
||||||
span.green Sprint Name
|
// span.green Sprint Name
|
||||||
span.date 02/10/2014-15/10/2014
|
// span.date 02/10/2014-15/10/2014
|
||||||
div.kanban-settings
|
div.kanban-settings
|
||||||
a.button.button-trans(href="", title="Filter")
|
// a.button.button-trans(href="", title="Filter")
|
||||||
span.icon.icon-filter
|
// span.icon.icon-filter
|
||||||
span Filters
|
// span Filters
|
||||||
a.button.button-gray(href="", title="Filter")
|
a.button.button-gray(href="", title="Filter")
|
||||||
span Show Statistics
|
span Show Statistics
|
||||||
//-include views/components/large-summary
|
//-include views/components/large-summary
|
||||||
include views/modules/burndown
|
//-include views/modules/burndown
|
||||||
//-include views/modules/list-filters-kanban
|
//-include views/modules/list-filters-kanban
|
||||||
include views/modules/kanban-table
|
include views/modules/kanban-table
|
||||||
|
|
|
@ -12,4 +12,4 @@ div.kanban-task-inner
|
||||||
a(href="", title="Change assignation") Username
|
a(href="", title="Change assignation") Username
|
||||||
a.icon.icon-edit(href="", title="Edit", ng-click="ctrl.editTask(task)")
|
a.icon.icon-edit(href="", title="Edit", ng-click="ctrl.editTask(task)")
|
||||||
a.icon.icon-drag-h(href="", title="Drag&Drop")
|
a.icon.icon-drag-h(href="", title="Drag&Drop")
|
||||||
a.task-points(href="", title="task points") 8
|
a.task-points(href="", title="task points", tg-bo-html="us.total_points") --
|
||||||
|
|
|
@ -1,51 +1,13 @@
|
||||||
div.kanban-table
|
div.kanban-table
|
||||||
div.kanban-table-header
|
div.kanban-table-header
|
||||||
div.kanban-table-inner
|
div.kanban-table-inner
|
||||||
h2.task-colum_name
|
h2.task-colum_name(ng-repeat="s in usStatusList track by s.id")
|
||||||
span Task
|
span(tg-bo-html="s.name")
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
|
||||||
h2.task-colum_name
|
|
||||||
span Open
|
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
|
||||||
h2.task-colum_name
|
|
||||||
span Ready for test
|
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
|
||||||
h2.task-colum_name
|
|
||||||
span Closed
|
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
|
||||||
h2.task-colum_name
|
|
||||||
span Task
|
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
|
||||||
h2.task-colum_name
|
|
||||||
span Open
|
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
|
||||||
h2.task-colum_name
|
|
||||||
span Ready for test
|
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
|
||||||
h2.task-colum_name
|
|
||||||
span Closed
|
|
||||||
a.icon.icon-plus(href="", title="Add New task")
|
a.icon.icon-plus(href="", title="Add New task")
|
||||||
|
|
||||||
div.kanban-table-body
|
div.kanban-table-body
|
||||||
div.kanban-table-inner
|
div.kanban-table-inner
|
||||||
div.taskboard_task-playground.task-column
|
div.taskboard_task-playground.task-column(ng-repeat="s in usStatusList track by s.id",
|
||||||
div.kanban-task
|
tg-kanban-sortable)
|
||||||
include ../components/kanban-task
|
div.kanban-task(ng-repeat="us in usByStatus[s.id] track by us.id")
|
||||||
div.taskboard_task-playground.task-column
|
|
||||||
div.kanban-task
|
|
||||||
include ../components/kanban-task
|
|
||||||
div.taskboard_task-playground.task-column
|
|
||||||
|
|
||||||
div.taskboard_task-playground.task-column
|
|
||||||
div.kanban-task
|
|
||||||
include ../components/kanban-task
|
|
||||||
div.taskboard_task-playground.task-column
|
|
||||||
div.kanban-task
|
|
||||||
include ../components/kanban-task
|
|
||||||
div.taskboard_task-playground.task-column
|
|
||||||
div.kanban-task
|
|
||||||
include ../components/kanban-task
|
|
||||||
div.taskboard_task-playground.task-column
|
|
||||||
|
|
||||||
div.taskboard_task-playground.task-column
|
|
||||||
div.kanban-task
|
|
||||||
include ../components/kanban-task
|
include ../components/kanban-task
|
||||||
|
|
|
@ -42,6 +42,7 @@ paths = {
|
||||||
"app/coffee/modules/common/*.coffee",
|
"app/coffee/modules/common/*.coffee",
|
||||||
"app/coffee/modules/backlog/*.coffee",
|
"app/coffee/modules/backlog/*.coffee",
|
||||||
"app/coffee/modules/taskboard/*.coffee",
|
"app/coffee/modules/taskboard/*.coffee",
|
||||||
|
"app/coffee/modules/kanban/*.coffee",
|
||||||
"app/coffee/modules/issues/*.coffee",
|
"app/coffee/modules/issues/*.coffee",
|
||||||
"app/coffee/modules/userstories/*.coffee",
|
"app/coffee/modules/userstories/*.coffee",
|
||||||
"app/coffee/modules/tasks/*.coffee",
|
"app/coffee/modules/tasks/*.coffee",
|
||||||
|
|
Loading…
Reference in New Issue