Epics dasboard
parent
5a3185e699
commit
cc02221a2d
|
@ -92,6 +92,9 @@ urls = {
|
||||||
# Milestones/Sprints
|
# Milestones/Sprints
|
||||||
"milestones": "/milestones"
|
"milestones": "/milestones"
|
||||||
|
|
||||||
|
# Epics
|
||||||
|
"epics": "/epics"
|
||||||
|
|
||||||
# User stories
|
# User stories
|
||||||
"userstories": "/userstories"
|
"userstories": "/userstories"
|
||||||
"bulk-create-us": "/userstories/bulk_create"
|
"bulk-create-us": "/userstories/bulk_create"
|
||||||
|
|
|
@ -401,7 +401,7 @@
|
||||||
"NAME": "Name",
|
"NAME": "Name",
|
||||||
"PROJECT": "Project",
|
"PROJECT": "Project",
|
||||||
"SPRINT": "Sprint",
|
"SPRINT": "Sprint",
|
||||||
"ASSIGNED_TO": "Assigned to",
|
"ASSIGNED_TO": "Assigned",
|
||||||
"STATUS": "Status",
|
"STATUS": "Status",
|
||||||
"PROGRESS": "Progress",
|
"PROGRESS": "Progress",
|
||||||
"VIEW_OPTIONS": "View options"
|
"VIEW_OPTIONS": "View options"
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014-2015 Taiga Agile LLC <taiga@taiga.io>
|
||||||
|
#
|
||||||
|
# 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: epics-table.controller.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
module = angular.module("taigaEpics")
|
||||||
|
|
||||||
|
class EpicRowController
|
||||||
|
@.$inject = [
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor: () ->
|
||||||
|
console.log @.epic.toJS()
|
||||||
|
|
||||||
|
module.controller("EpicRowCtrl", EpicRowController)
|
|
@ -0,0 +1,36 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
|
||||||
|
#
|
||||||
|
# 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: epics-table.directive.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
module = angular.module('taigaEpics')
|
||||||
|
|
||||||
|
EpicRowDirective = () ->
|
||||||
|
|
||||||
|
return {
|
||||||
|
templateUrl:"epics/dashboard/epic-row/epic-row.html",
|
||||||
|
controller: "EpicRowCtrl",
|
||||||
|
controllerAs: "vm",
|
||||||
|
bindToController: true,
|
||||||
|
scope: {
|
||||||
|
epic: '='
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EpicRowDirective.$inject = []
|
||||||
|
|
||||||
|
module.directive("tgEpicRow", EpicRowDirective)
|
|
@ -0,0 +1,29 @@
|
||||||
|
.epic-row
|
||||||
|
.vote(ng-class="{'is-voter': vm.epic.get('is_voter')}")
|
||||||
|
tg-svg(svg-icon='icon-upvote')
|
||||||
|
span {{::vm.epic.get('total_voters')}}
|
||||||
|
|
||||||
|
.name() {{::vm.epic.get('subject')}}
|
||||||
|
|
||||||
|
.project() {{::vm.epic.get('project')}}
|
||||||
|
.sprint(
|
||||||
|
translate="EPICS.TABLE.SPRINT"
|
||||||
|
)
|
||||||
|
.assigned(
|
||||||
|
ng-if="vm.epic.getIn(['assigned_to_extra_info', 'photo'])"
|
||||||
|
)
|
||||||
|
img(
|
||||||
|
ng-src="{{vm.epic.getIn(['assigned_to_extra_info', 'photo'])}}"
|
||||||
|
alt="::vm.epic.getIn(['assigned_to_extra_info', 'name'])"
|
||||||
|
)
|
||||||
|
.assigned(
|
||||||
|
ng-if="!vm.epic.getIn(['assigned_to_extra_info', 'photo'])"
|
||||||
|
) Unassigned
|
||||||
|
.status(
|
||||||
|
ng-style="{'color': vm.epic.getIn(['status_extra_info', 'color'])}"
|
||||||
|
)
|
||||||
|
span {{::vm.epic.getIn(['status_extra_info', 'name'])}}
|
||||||
|
tg-svg(svg-icon="icon-arrow-down")
|
||||||
|
.progress
|
||||||
|
.progress-bar
|
||||||
|
.progress-status
|
|
@ -0,0 +1,31 @@
|
||||||
|
.epic-row {
|
||||||
|
@include font-size(small);
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid $whitish;
|
||||||
|
display: flex;
|
||||||
|
.progress-bar,
|
||||||
|
.progress-status {
|
||||||
|
height: 1.5rem;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: .25rem;
|
||||||
|
}
|
||||||
|
.progress-bar {
|
||||||
|
background: $mass-white;
|
||||||
|
max-width: 40vw;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.progress-status {
|
||||||
|
background: $primary-light;
|
||||||
|
width: 10vw;
|
||||||
|
}
|
||||||
|
.vote {
|
||||||
|
color: $gray;
|
||||||
|
}
|
||||||
|
.icon-upvote {
|
||||||
|
@include svg-size(.75rem);
|
||||||
|
fill: $gray;
|
||||||
|
margin-right: .25rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,7 +34,7 @@ class EpicsDashboardController
|
||||||
return @rs.projects.getBySlug(@params.pslug).then (project) =>
|
return @rs.projects.getBySlug(@params.pslug).then (project) =>
|
||||||
if not project.is_epics_activated
|
if not project.is_epics_activated
|
||||||
@errorHandlingService.permissionDenied()
|
@errorHandlingService.permissionDenied()
|
||||||
@project = project
|
@.project = project
|
||||||
|
|
||||||
addNewEpic: () ->
|
addNewEpic: () ->
|
||||||
console.log 'Add new Epic'
|
console.log 'Add new Epic'
|
||||||
|
|
|
@ -16,4 +16,7 @@ doctype html
|
||||||
ng-click="vm.addNewEpic()"
|
ng-click="vm.addNewEpic()"
|
||||||
)
|
)
|
||||||
|
|
||||||
tg-epics-table
|
tg-epics-table(
|
||||||
|
ng-if="vm.project"
|
||||||
|
project="vm.project"
|
||||||
|
)
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
module = angular.module("taigaEpics")
|
module = angular.module("taigaEpics")
|
||||||
|
|
||||||
class EpicsTableController
|
class EpicsTableController
|
||||||
@.$inject = []
|
@.$inject = [
|
||||||
|
"tgResources"
|
||||||
|
]
|
||||||
|
|
||||||
constructor: () ->
|
constructor: (@rs) ->
|
||||||
@.displayOptions = false
|
@.displayOptions = false
|
||||||
@.displayVotes = true
|
@.displayVotes = true
|
||||||
@.column = {
|
@.column = {
|
||||||
|
@ -34,11 +36,15 @@ class EpicsTableController
|
||||||
status: true,
|
status: true,
|
||||||
progress: true
|
progress: true
|
||||||
}
|
}
|
||||||
|
@._loadEpics()
|
||||||
|
|
||||||
toggleEpicTableOptions: () ->
|
toggleEpicTableOptions: () ->
|
||||||
@.displayOptions = !@.displayOptions
|
@.displayOptions = !@.displayOptions
|
||||||
|
|
||||||
updateEpicTableColumns: () ->
|
_loadEpics: () ->
|
||||||
console.log @.column
|
projectId = @.project.id
|
||||||
|
params = {}
|
||||||
|
promise = @rs.epics.listAll(projectId, params).then (epics) =>
|
||||||
|
@.epics = epics
|
||||||
|
|
||||||
module.controller("EpicsTableCtrl", EpicsTableController)
|
module.controller("EpicsTableCtrl", EpicsTableController)
|
||||||
|
|
|
@ -26,7 +26,9 @@ EpicsTableDirective = () ->
|
||||||
controller: "EpicsTableCtrl",
|
controller: "EpicsTableCtrl",
|
||||||
controllerAs: "vm",
|
controllerAs: "vm",
|
||||||
bindToController: true,
|
bindToController: true,
|
||||||
scope: {}
|
scope: {
|
||||||
|
project: "="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EpicsTableDirective.$inject = []
|
EpicsTableDirective.$inject = []
|
||||||
|
|
|
@ -6,7 +6,6 @@ mixin epicSwitch(name, model)
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
ng-checked= model
|
ng-checked= model
|
||||||
ng-model= model
|
ng-model= model
|
||||||
ng-change="vm.updateEpicTableColumns()"
|
|
||||||
)
|
)
|
||||||
div
|
div
|
||||||
span.check-text.check-yes(translate="COMMON.YES")
|
span.check-text.check-yes(translate="COMMON.YES")
|
||||||
|
@ -90,10 +89,7 @@ mixin epicSwitch(name, model)
|
||||||
)
|
)
|
||||||
+epicSwitch('switch-progress', 'vm.column.progress')
|
+epicSwitch('switch-progress', 'vm.column.progress')
|
||||||
.epics-table-body
|
.epics-table-body
|
||||||
.vote
|
.epics-table-body-row(tg-repeat="epic in vm.epics track by epic.get('id')")
|
||||||
.name
|
tg-epic-row(
|
||||||
.project
|
epic="epic"
|
||||||
.sprint
|
)
|
||||||
.assigned
|
|
||||||
.status
|
|
||||||
.progress
|
|
||||||
|
|
|
@ -4,23 +4,40 @@
|
||||||
|
|
||||||
.epics-table-header,
|
.epics-table-header,
|
||||||
.epics-table-body {
|
.epics-table-body {
|
||||||
display: flex;
|
|
||||||
.assigned,
|
.assigned,
|
||||||
|
.project,
|
||||||
|
.vote,
|
||||||
|
.status,
|
||||||
|
.sprint,
|
||||||
|
.name,
|
||||||
|
.progress {
|
||||||
|
padding: 1rem .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.assigned,
|
||||||
|
.project,
|
||||||
.vote {
|
.vote {
|
||||||
flex-basis: 100px;
|
flex-basis: 80px;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.status,
|
.status,
|
||||||
.sprint {
|
.sprint {
|
||||||
flex-basis: 200px;
|
flex-basis: 150px;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.name,
|
.name,
|
||||||
.project,
|
|
||||||
.progress {
|
.progress {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
max-width: 40vw;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 90%;
|
||||||
}
|
}
|
||||||
.progress {
|
.progress {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -30,12 +47,9 @@
|
||||||
.epics-table-header {
|
.epics-table-header {
|
||||||
@include font-type(bold);
|
@include font-type(bold);
|
||||||
border-bottom: 1px solid $gray-light;
|
border-bottom: 1px solid $gray-light;
|
||||||
|
display: flex;
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
.epics-table-options {
|
|
||||||
@include font-type(text);
|
|
||||||
@include font-size(small);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.epics-table-options-wrapper {
|
.epics-table-options-wrapper {
|
||||||
|
@ -46,6 +60,7 @@
|
||||||
|
|
||||||
.epics-table-option-button {
|
.epics-table-option-button {
|
||||||
@include font-type(light);
|
@include font-type(light);
|
||||||
|
@include font-size(small);
|
||||||
background: none;
|
background: none;
|
||||||
.icon {
|
.icon {
|
||||||
@include svg-size(.7rem);
|
@include svg-size(.7rem);
|
||||||
|
@ -54,11 +69,14 @@
|
||||||
|
|
||||||
.epics-table-dropdown {
|
.epics-table-dropdown {
|
||||||
background: $white;
|
background: $white;
|
||||||
|
border-bottom: 1px solid rgba($black, .1);
|
||||||
|
border-left: 1px solid rgba($black, .1);
|
||||||
|
border-right: 1px solid rgba($black, .1);
|
||||||
box-shadow: 3px 3px 2px rgba($black, .1);
|
box-shadow: 3px 3px 2px rgba($black, .1);
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 1.25rem;
|
top: 1.3rem;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
.fieldset {
|
.fieldset {
|
||||||
@include font-size(small);
|
@include font-size(small);
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
|
||||||
|
#
|
||||||
|
# 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: epics-resource.service.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
Resource = (urlsService, http) ->
|
||||||
|
service = {}
|
||||||
|
|
||||||
|
service.listAll = (params) ->
|
||||||
|
url = urlsService.resolve("epics")
|
||||||
|
|
||||||
|
httpOptions = {}
|
||||||
|
|
||||||
|
return http.get(url, params, httpOptions).then (result) ->
|
||||||
|
return Immutable.fromJS(result.data)
|
||||||
|
|
||||||
|
return () ->
|
||||||
|
return {"epics": service}
|
||||||
|
|
||||||
|
Resource.$inject = ["$tgUrls", "$tgHttp"]
|
||||||
|
|
||||||
|
module = angular.module("taigaResources2")
|
||||||
|
module.factory("tgEpicsResource", Resource)
|
|
@ -27,7 +27,8 @@ services = [
|
||||||
"tgExternalAppsResource",
|
"tgExternalAppsResource",
|
||||||
"tgAttachmentsResource",
|
"tgAttachmentsResource",
|
||||||
"tgStatsResource",
|
"tgStatsResource",
|
||||||
"tgWikiHistory"
|
"tgWikiHistory",
|
||||||
|
"tgEpicsResource"
|
||||||
]
|
]
|
||||||
|
|
||||||
Resources = ($injector) ->
|
Resources = ($injector) ->
|
||||||
|
|
Loading…
Reference in New Issue