Merge branch 'master' into us-detail

Conflicts:
	app/styles/main.scss
stable
Xavier Julián 2014-06-23 13:09:24 +02:00
commit 76d07c2fd1
25 changed files with 368 additions and 118 deletions

View File

@ -22,7 +22,9 @@
@taiga = taiga = {}
configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $compileProvider, $gmUrlsProvider) ->
$routeProvider.when('/project/:pslug/backlog', {templateUrl: '/partials/backlog.html'})
$routeProvider.when("/project/:pslug/backlog", {templateUrl: "/partials/backlog.html"})
$routeProvider.when("/login", {templateUrl: "/partials/login.html"})
$routeProvider.otherwise({redirectTo: '/login'})
$locationProvider.html5Mode(true);
@ -80,6 +82,3 @@ angular.module("taigaLocalConfig", []).value("localconfig", {})
module = angular.module("taiga", modules)
module.config(configure)
module.run(init)

View File

@ -22,9 +22,9 @@
taiga = @.taiga
class AuthService extends taiga.Service
@.$inject = ["$rootScope", "$tgStorage", "$tgModel", "$tgHttp"]
@.$inject = ["$rootScope", "$tgStorage", "$tgModel", "$tgHttp", "$tgUrls"]
constructor: (@rootscope, @storage, @model, @http) ->
constructor: (@rootscope, @storage, @model, @http, @urls) ->
super()
getUser: ->
@ -60,11 +60,12 @@ class AuthService extends taiga.Service
data = {
username: username
password: password
type: "normal"
}
return @http.post(url, data).then (data, status) =>
user = @model.make_model("users", data)
@.setToken(data["auth_token"])
user = @model.make_model("users", data.data)
@.setToken(user.auth_token)
@.setUser(user)
return user
@ -73,5 +74,19 @@ class AuthService extends taiga.Service
return true
return false
class AuthController extends taiga.Controller
@.$inject = ["$scope", "$tgAuth", "$location"]
constructor: (@scope, @auth, @location) ->
@scope.form = {username: "", password: ""}
submit: ->
@auth.login(@scope.form.username, @scope.form.password).then (user) =>
#TODO: fix this
@location.path("/project/project-example-0/backlog")
module = angular.module("taigaAuth", ["taigaResources"])
module.service("$tgAuth", AuthService)
module.controller("AuthController", AuthController)

View File

@ -31,6 +31,22 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin)
@rootscope.$on("usform:bulk:success", @.loadUserstories)
initializeProjectStats: ->
@scope.stats = {
total_points: "--"
defined_points: "--"
assigned_points: "--"
closed_points: "--"
completedPercentage: "--%"
}
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
loadSprints: ->
return @rs.sprints.list(@scope.projectId).then (sprints) =>
@scope.sprints = sprints
@ -46,6 +62,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin)
loadBacklog: ->
return @q.all([
@.loadProjectStats(),
@.loadSprints(),
@.loadUserstories()
])
@ -58,6 +75,9 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin)
return project
loadInitialData: ->
# Set stats initial values
@.initializeProjectStats()
# Resolve project slug
promise = @repo.resolve({pslug: @params.pslug}).then (data) =>
@scope.projectId = data.project
@ -213,7 +233,12 @@ BacklogDirective = ($repo) ->
#############################################################################
BacklogSprintDirective = ($repo) ->
link = ($scope, $el, $attrs) ->
#########################
## Common parts
#########################
linkCommon = ($scope, $el, $attrs, $ctrl) ->
$ctrl = $el.closest("div.wrapper").controller()
sprint = $scope.$eval($attrs.tgBacklogSprint)
@ -223,15 +248,28 @@ BacklogSprintDirective = ($repo) ->
if sprint.closed
$el.addClass("sprint-closed")
if not $scope.$first and not sprint.closed
$el.addClass("sprint-old-open")
# Atatch formatted dates
initialDate = moment(sprint.estimated_start).format("YYYY/MM/DD")
finishDate = moment(sprint.estimated_finish).format("YYYY/MM/DD")
dates = "#{initialDate}-#{finishDate}"
$el.find(".sprint-date").html(dates)
# Update progress bars
progressPercentage = Math.round(100 * (sprint.closed_points / sprint.total_points))
$el.find(".current-progress").css("width", "#{progressPercentage}%")
# Event Handlers
$el.on "click", ".sprint-summary > a", (event) ->
$el.find(".sprint-table").toggle()
$scope.$on "$destroy", ->
$el.off()
# Drag & Drop
#########################
## Drag & Drop Link
#########################
linkSortable = ($scope, $el, $attrs, $ctrl) ->
resortAndSave = ->
toSave = []
for item, i in $scope.sprint.user_stories
@ -292,6 +330,14 @@ BacklogSprintDirective = ($repo) ->
onRemove: onRemoveItem,
})
link = ($scope, $el, $attrs) ->
$ctrl = $el.controller()
linkSortable($scope, $el, $attrs, $ctrl)
linkCommon($scope, $el, $attrs, $ctrl)
$scope.$on "$destroy", ->
$el.off()
return {link: link}

View File

@ -39,10 +39,12 @@ resourceProvider = ($repo) ->
params = {"project": projectId}
return $repo.queryMany("roles", params)
service.stats = (projectId) ->
return $repo.queryOneRaw("projects", "#{projectId}/stats")
return (instance) ->
instance.projects = service
module = angular.module("taigaResources")
module.factory("$tgProjectsResourcesProvider", ["$tgRepo", resourceProvider])

20
app/partials/issues.jade Normal file
View File

@ -0,0 +1,20 @@
extends layout
block head
title Taiga Project management web application with scrum in mind!
block content
div.wrapper
sidebar.menu-secondary.sidebar
header
h1 Filters
include views/modules/search-in
include views/modules/filter-tags
section.main.issues-page
header
include views/components/mainTitle
include views/modules/list-filters
include views/modules/issues-table

16
app/partials/kanban.jade Normal file
View File

@ -0,0 +1,16 @@
extends layout
block head
title Taiga Project management web application with scrum in mind!
block content
div.wrapper
section.main.kanban
h1
span ProjectName
span.green Sprint Name
span.date 02/10/2014-15/10/2014
include views/components/large-summary
include views/modules/burndown
include views/modules/list-filters-kanban
include views/modules/taskboard-table

11
app/partials/login.jade Normal file
View File

@ -0,0 +1,11 @@
extends dummy-layout
block head
title Taiga Project management web application with scrum in mind!
block content
div.wrapper(ng-controller="AuthController as ctrl")
form(ng-submit="ctrl.submit()")
input(type="text", name="username", ng-model="form.username", placeholder="User name")
input(type="password", name="password", ng-model="form.password", placeholder="Password")
input(type="submit", value="Submit")

View File

@ -2,18 +2,18 @@ div.summary(tg-backlog-summary)
div.summary-progress-bar
div.current-progress
div.data
span.number 30%
span.number(ng-bind="stats.completedPercentage")
span.description completed
ul
li
span.number 12
span.number(ng-bind="stats.total_points")
span.description project<br />points
li
span.number 23
span.number(ng-bind="stats.defined_points")
span.description defined<br />points
li
span.number 12
span.number(ng-bind="stats.assigned_points")
span.description assigned<br />points
li
span.number 23
span.number(ng-bind="stats.closed_points")
span.description closed<br />points

View File

@ -0,0 +1,12 @@
section.filter-tags
div.filter-tag.active(style="background-color: red")
div.tag-name Tagname
div.tag-count 4
div.filter-tag(style="background-color: blue")
div.tag-name Tagname
div.tag-count 4
div.filter-tag(style="background-color: green")
div.tag-name Tagname
div.tag-count 4

View File

@ -0,0 +1,21 @@
section.issues-table
div.row.title
div.level-field.width-1 Severity
div.level-field.width-1 Priority
div.width-7.subject Subject
div.width-2 Status
div.width-2 Assigned to
- for (var x = 0; x < 50; x++)
div.row.table-main
div.level-field.width-1
div.level
div.level-field.width-1
div.level
div.width-7.subject
| #2 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sit amet leo accumsan, commodo neque eu, iaculis nisl. Phasellus fermentum ipsum eget sapien suscipit pretium.
div.width-2
In progress
div.width-2
figure.avatar
img(src="http://thecodeplayer.com/u/uifaces/12.jpg", alt="username")
figcaption Pilar

View File

@ -0,0 +1,23 @@
section.list-filters
ul
li
a(href="#").active
span.icon.icon-filter
| SHOW FILTERS
li
a(href="#")
span.icon.icon-tag
| SHOW TAGS
li
a(href="#")
span.icon.icon-graph
| HIDE CFD GRAPH
div.new-issue
a.button-green(href="")
span.text
| + NEW TASK
a.button-bulk(href="")
span.icon.icon-bulk

View File

@ -0,0 +1,18 @@
section.list-filters
ul
li
a(href="#").active
span.icon.icon-issues
| SHOW LIST
li
a(href="#")
span.icon.icon-graph
| SHOW GRAPH
div.new-issue
a.button-green(href="")
span.text
| + NEW ISSUE
a.button-bulk(href="")
span.icon.icon-bulk

View File

@ -1,4 +1,4 @@
section.search
section.search-in
header
form
fieldset

View File

@ -4,8 +4,8 @@ section.sprints
div.summary
ul
li
span.number 12
span.description project<br />points
span.number(tg-bo-html="stats.total_milestones") --
span.description <br/>sprints
div.new-sprint
a.button-green(href="", title="Add New US")
span.text + New sprint
@ -15,13 +15,13 @@ section.sprints
div.sprint-summary
a.icon.icon-arrow-up(href="", title="compact Sprint")
span.sprint-name current sprint
span.sprint-date 04/06/14-20/06/14
span.sprint-date
ul
li
span.number 12
span.number(tg-bo-html="sprint.closed_points") --
span.description closed<br />points
li
span.number 24
span.number(tg-bo-html="sprint.total_points") --
span.description total<br />points
div.sprint-progress-bar
div.current-progress
@ -35,74 +35,3 @@ section.sprints
a.button.button-gray(href="", tg-nav="project-taskboard:project=projectId,sprint=sprint.id",
title="Current Sprint Taskboard")
span Sprint Taskboard
// If is current sprint
// section.sprint.sprint-current
// header
// div.sprint-summary
// a.icon.icon-arrow-up(href="", title="compact Sprint")
// span.sprint-name current sprint
// span.sprint-date 04/06/14-20/06/14
// ul
// li
// span.number 12
// span.description closed<br />points
// li
// span.number 24
// span.description total<br />points
// div.sprint-progress-bar
// div.current-progress
// div.sprint-table
// - for (var x = 0; x < 10; x++)
// div.row
// div.column-us.width-8
// a.us-name(href="", title="") #125 Crear el perfil de usuario Senior en el admin
// div.column-points.width-1 45
// a.button.button-gray(href="", title="Current Sprint Taksboard")
// span Sprint Taskboard
// // If Sprint is open but date is old
// section.sprint.sprint-old-open
// header
// div.sprint-summary
// a.icon.icon-arrow-up(href="", title="compact Sprint")
// span.sprint-name old open sprint
// span.sprint-date 04/05/14-03/06/14
// ul
// li
// span.number 20
// span.description closed<br />points
// li
// span.number 24
// span.description total<br />points
// div.sprint-progress-bar
// div.current-progress
// div.sprint-table
// - for (var x = 0; x < 10; x++)
// div.row
// div.column-us.width-8
// a(href="", title="") #125 Crear el perfil de usuario Senior en el admin
// div.column-points.width-1 45
// // If Sprint is closed and date is old
// section.sprint.sprint-closed
// header
// div.sprint-summary
// a.icon.icon-arrow-up(href="", title="compact Sprint")
// span.sprint-name old sprint
// span.sprint-date 04/04/14-03/05/14
// ul
// li
// span.number 24
// span.description closed<br />points
// li
// span.number 24
// span.description total<br />points
// div.sprint-progress-bar
// div.current-progress
// div.sprint-table
// - for (var x = 0; x < 10; x++)
// div.row
// div.column-us.width-8
// a(href="", title="") #125 Crear el perfil de usuario Senior en el admin
// div.column-points.width-1 45

View File

@ -4,12 +4,6 @@ fieldset {
padding: 0;
position: relative;
width: 100%;
// xavi pleeeeeease
// .icon {
// position: absolute;
// right: 10px;
// top: 6px;
// }
}
input[type="text"],

View File

@ -0,0 +1,13 @@
.admin-membership {
header {
@include clearfix;
margin-bottom: 1rem;
h1 {
float: left;
margin-bottom: 0;
}
a {
float: right;
}
}
}

View File

@ -0,0 +1,8 @@
.kanban {
.burndown-container {
display: none;
}
.list-filters {
margin-bottom: 1rem;
}
}

View File

@ -35,11 +35,15 @@ $prefix-for-spec: true;
@import 'modules/taskboard-table';
@import 'modules/search-filter';
@import 'modules/search-result-table';
@import 'modules/search-in';
@import 'modules/issues-table';
@import 'modules/list-filters';
@import 'modules/filter-tags';
@import 'modules/admin-menu';
@import 'modules/admin-submenu';
@import 'modules/admin-membership';
@import 'modules/admin-roles';
@import 'modules/admin-functionalities';
@import 'modules/admin-membership-table';
@import 'modules/category-config';
@import 'modules/project-details';
@import 'modules/attachments';
@ -56,3 +60,5 @@ $prefix-for-spec: true;
@import 'layout/backlog';
@import 'layout/taskboard';
@import 'layout/us-detail';
@import 'layout/admin-membership';
@import 'layout/kanban';

View File

@ -1,17 +1,3 @@
.admin-membership {
header {
@include clearfix;
margin-bottom: 1rem;
h1 {
float: left;
margin-bottom: 0;
}
a {
float: right;
}
}
}
.admin-membership-table {
align-content: stretch;
align-items: center;

View File

@ -0,0 +1,21 @@
.filter-tags {
margin-top: 2rem;
.filter-tag {
color: $white;
cursor: pointer;
margin-bottom: 1rem;
opacity: .5;
padding: .5rem 1rem;
position: relative;
&.active {
opacity: 1;
}
}
.tag-count {
background: none repeat scroll 0 0 rgba(0, 0, 0, .3);
padding: .5rem 1rem;
position: absolute;
right: 0;
top: 0;
}
}

View File

@ -0,0 +1,70 @@
.issues-table {
align-content: stretch;
align-items: center;
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: flex-start;
width: 100%;
.row {
align-content: stretch;
align-items: center;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
padding: 1rem 0;
text-align: left;
width: 100%;
@for $i from 1 through 8 {
.width-#{$i} {
flex-basis: 50px;
flex-grow: $i;
flex-shrink: 0;
}
}
&:hover {
background: lighten($green-taiga, 60%);
@include transition (background .2s ease-in);
}
}
.row-selected {
background: lighten($green-taiga, 60%);
@include transition (background .2s ease-in);
}
.title {
@extend %medium;
border-bottom: 1px solid $gray-light;
font-family: 'DroidSans-Bold';
&:hover {
background: transparent;
}
}
.table-main {
@extend %small;
border-bottom: 1px solid $gray-light;
}
.avatar {
align-items: center;
display: flex;
img {
flex-basis: 35px;
}
figcaption {
margin-left: 1rem;
}
}
.level {
background-color: $gray-light;
border-radius: 9px;
height: 18px;
margin: 0 auto;
width: 18px;
}
.level-field {
text-align: center;
}
.subject {
padding-right: 1rem;
}
}

View File

@ -0,0 +1,29 @@
.list-filters {
align-items: center;
background-color: $whitish;
display: flex;
justify-content: space-between;
padding: .5rem 1rem;
ul {
display: flex;
margin-bottom: 0;
}
li {
margin-right: 2rem;
a {
@extend %large;
font-family: 'ostrichSans';
opacity: .4;
&.active,
&:hover {
@include transition (opacity .3s linear);
color: $blackish;
opacity: 1;
}
}
.icon {
padding-right: .5rem;
}
}
}

View File

@ -0,0 +1,7 @@
.search-in {
.icon {
position: absolute;
right: 10px;
top: 6px;
}
}

View File

@ -18,6 +18,9 @@
margin: 0 .3rem;
padding: .5rem 0;
text-align: center;
&:first-child {
margin-left: 0;
}
}
}

View File

@ -51,7 +51,8 @@ paths = {
"app/vendor/angular-sanitize/angular-sanitize.js",
"app/vendor/angular-animate/angular-animate.js",
"app/vendor/i18next/i18next.js",
"app/js/Sortable.js"
"app/js/Sortable.js",
"app/vendor/moment/min/moment-with-langs.js"
]
}