Create Epic
parent
01b5717783
commit
ebe8c159f6
|
@ -412,6 +412,14 @@
|
||||||
"STATUS": "Status",
|
"STATUS": "Status",
|
||||||
"PROGRESS": "Progress",
|
"PROGRESS": "Progress",
|
||||||
"VIEW_OPTIONS": "View options"
|
"VIEW_OPTIONS": "View options"
|
||||||
|
},
|
||||||
|
"CREATE": {
|
||||||
|
"TITLE": "New Epic",
|
||||||
|
"TEAM_REQUIREMENT": "Team requirement",
|
||||||
|
"CLIENT_REQUIREMENT": "Client requirement",
|
||||||
|
"BLOCKED": "Blocked",
|
||||||
|
"BLOCKED_NOTE_PLACEHOLDER": "Why is this epic blocked?",
|
||||||
|
"CREATE_EPIC": "Create epic"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PROJECTS": {
|
"PROJECTS": {
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
###
|
||||||
|
# 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: create-epic.controller.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
module = angular.module("taigaEpics")
|
||||||
|
|
||||||
|
class CreateEpicController
|
||||||
|
@.$inject = [
|
||||||
|
"tgResources",
|
||||||
|
"$tgConfirm",
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor: (@rs, @confirm) ->
|
||||||
|
@.attachments = Immutable.List()
|
||||||
|
|
||||||
|
createEpic: () ->
|
||||||
|
@.newEpic.project = @.project.id
|
||||||
|
return @rs.epics.post(@.newEpic).then () =>
|
||||||
|
@confirm.notify("success")
|
||||||
|
@.onReloadEpics()
|
||||||
|
|
||||||
|
|
||||||
|
module.controller("CreateEpicCtrl", CreateEpicController)
|
|
@ -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: create-epic.directive.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
module = angular.module('taigaEpics')
|
||||||
|
|
||||||
|
CreateEpicDirective = () ->
|
||||||
|
|
||||||
|
return {
|
||||||
|
templateUrl:"epics/create-epic/create-epic.html",
|
||||||
|
controller: "CreateEpicCtrl",
|
||||||
|
controllerAs: "vm",
|
||||||
|
bindToController: true,
|
||||||
|
scope: {
|
||||||
|
project: '=',
|
||||||
|
onReloadEpics: '&'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateEpicDirective.$inject = []
|
||||||
|
|
||||||
|
module.directive("tgCreateEpic", CreateEpicDirective)
|
|
@ -0,0 +1,90 @@
|
||||||
|
tg-lightbox-close
|
||||||
|
|
||||||
|
.create-epic-container
|
||||||
|
h2.title(translate="EPICS.CREATE.TITLE")
|
||||||
|
form(
|
||||||
|
ng-submit="vm.createEpic()"
|
||||||
|
)
|
||||||
|
fieldset
|
||||||
|
input(
|
||||||
|
type="text"
|
||||||
|
name="subject"
|
||||||
|
maxlength="140"
|
||||||
|
ng-model="vm.newEpic.subject"
|
||||||
|
tg-auto-select
|
||||||
|
placeholder="{{'COMMON.FIELDS.SUBJECT' | translate}}"
|
||||||
|
required
|
||||||
|
)
|
||||||
|
fieldset
|
||||||
|
select(
|
||||||
|
id="epic-status"
|
||||||
|
name="status"
|
||||||
|
ng-model="vm.newEpic.status"
|
||||||
|
)
|
||||||
|
option(
|
||||||
|
ng-repeat="status in vm.project.epic_statuses | orderBy:'order'"
|
||||||
|
ng-value="status.id"
|
||||||
|
ng-selected="vm.project.default_epic_status"
|
||||||
|
) {{status.name}}
|
||||||
|
fieldset.tags-block(
|
||||||
|
tg-lb-tag-line
|
||||||
|
ng-model="vm.newEpic.tags"
|
||||||
|
)
|
||||||
|
fieldset
|
||||||
|
textarea(
|
||||||
|
ng-attr-placeholder="{{'COMMON.FIELDS.DESCRIPTION' | translate}}"
|
||||||
|
ng-model="vm.newEpic.description"
|
||||||
|
)
|
||||||
|
fieldset
|
||||||
|
tg-attachments-simple(
|
||||||
|
attachments="vm.attachments"
|
||||||
|
)
|
||||||
|
.settings
|
||||||
|
fieldset.team-requirement
|
||||||
|
input(
|
||||||
|
type="checkbox"
|
||||||
|
name="team_requirement"
|
||||||
|
ng-model="vm.newEpic.teamRequirement"
|
||||||
|
id="team-requirement"
|
||||||
|
)
|
||||||
|
label.requirement.trans-button(
|
||||||
|
for="team-requirement"
|
||||||
|
translate="EPICS.CREATE.TEAM_REQUIREMENT"
|
||||||
|
)
|
||||||
|
fieldset.client-requirement
|
||||||
|
input(
|
||||||
|
type="checkbox"
|
||||||
|
name="client_requirement"
|
||||||
|
ng-model="vm.newEpic.clientRequirement"
|
||||||
|
id="client-requirement"
|
||||||
|
)
|
||||||
|
label.requirement.trans-button(
|
||||||
|
for="client-requirement"
|
||||||
|
translate="EPICS.CREATE.CLIENT_REQUIREMENT"
|
||||||
|
)
|
||||||
|
fieldset
|
||||||
|
input(
|
||||||
|
type="checkbox"
|
||||||
|
name="blocked"
|
||||||
|
ng-model="vm.newEpic.isBlocked"
|
||||||
|
id="blocked"
|
||||||
|
ng-click="displayBlockedReason = !displayBlockedReason"
|
||||||
|
)
|
||||||
|
label.requirement.trans-button.blocked(
|
||||||
|
for="blocked"
|
||||||
|
translate="EPICS.CREATE.BLOCKED"
|
||||||
|
)
|
||||||
|
fieldset(ng-if="displayBlockedReason")
|
||||||
|
input(
|
||||||
|
type="text"
|
||||||
|
name="blocked_note"
|
||||||
|
maxlength="140"
|
||||||
|
ng-model="vm.newEpic.blocked_note"
|
||||||
|
placeholder="{{'EPICS.CREATE.BLOCKED_NOTE_PLACEHOLDER' | translate}}"
|
||||||
|
)
|
||||||
|
fieldset
|
||||||
|
input.button-green.create-epic-button(
|
||||||
|
type="submit"
|
||||||
|
translate="EPICS.CREATE.CREATE_EPIC"
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
.lightbox-create-epic {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 1;
|
||||||
|
.create-epic-container {
|
||||||
|
max-width: 700px;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
.attachments {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.settings {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
fieldset {
|
||||||
|
margin-right: .5rem;
|
||||||
|
&:hover {
|
||||||
|
color: $white;
|
||||||
|
transition: all .2s ease-in;
|
||||||
|
transition-delay: .2s;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
&:checked+label {
|
||||||
|
background: $primary;
|
||||||
|
border: 1px solid $primary;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
&:checked+.blocked {
|
||||||
|
background: $red;
|
||||||
|
border: 1px solid $red;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
@include font-size(small);
|
||||||
|
background: $mass-white;
|
||||||
|
border: 1px solid $gray-light;
|
||||||
|
color: $gray-light;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
padding: .5rem 3rem;
|
||||||
|
text-transform: none;
|
||||||
|
transition: all .2s ease-in;
|
||||||
|
&:hover {
|
||||||
|
background: $primary-light;
|
||||||
|
border: 1px solid $primary;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
&.blocked {
|
||||||
|
&:hover {
|
||||||
|
background: $red-light;
|
||||||
|
border: 1px solid $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.create-epic-button {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ class EpicRowController
|
||||||
constructor: (@rs, @confirm) ->
|
constructor: (@rs, @confirm) ->
|
||||||
@.displayUserStories = false
|
@.displayUserStories = false
|
||||||
@._calculateProgressBar()
|
@._calculateProgressBar()
|
||||||
|
@.displayAssignedTo = false
|
||||||
|
|
||||||
_calculateProgressBar: () ->
|
_calculateProgressBar: () ->
|
||||||
totalUs = @.epic.getIn(['user_stories_counts', 'closed'])
|
totalUs = @.epic.getIn(['user_stories_counts', 'closed'])
|
||||||
|
@ -67,6 +68,6 @@ class EpicRowController
|
||||||
@.displayUserStories = false
|
@.displayUserStories = false
|
||||||
|
|
||||||
onSelectAssignedTo: () ->
|
onSelectAssignedTo: () ->
|
||||||
console.log 'onSelectAssignedTo'
|
console.log 'Assigned to'
|
||||||
|
|
||||||
module.controller("EpicRowCtrl", EpicRowController)
|
module.controller("EpicRowCtrl", EpicRowController)
|
||||||
|
|
|
@ -24,12 +24,14 @@ class EpicsDashboardController
|
||||||
"$tgResources",
|
"$tgResources",
|
||||||
"tgResources",
|
"tgResources",
|
||||||
"$routeParams",
|
"$routeParams",
|
||||||
"tgErrorHandlingService"
|
"tgErrorHandlingService",
|
||||||
|
"tgLightboxFactory",
|
||||||
]
|
]
|
||||||
|
|
||||||
constructor: (@rs, @resources, @params, @errorHandlingService) ->
|
constructor: (@rs, @resources, @params, @errorHandlingService, @lightboxFactory) ->
|
||||||
@.sectionName = "Epics"
|
@.sectionName = "Epics"
|
||||||
@._loadProject()
|
@._loadProject()
|
||||||
|
@.createEpic = false
|
||||||
|
|
||||||
_loadProject: () ->
|
_loadProject: () ->
|
||||||
return @rs.projects.getBySlug(@params.pslug).then (project) =>
|
return @rs.projects.getBySlug(@params.pslug).then (project) =>
|
||||||
|
@ -43,7 +45,14 @@ class EpicsDashboardController
|
||||||
return @resources.epics.list(projectId).then (epics) =>
|
return @resources.epics.list(projectId).then (epics) =>
|
||||||
@.epics = epics
|
@.epics = epics
|
||||||
|
|
||||||
addNewEpic: () ->
|
onCreateEpic: () ->
|
||||||
console.log 'Add new Epic'
|
@lightboxFactory.create('tg-create-epic', {
|
||||||
|
"class": "lightbox lightbox-create-epic"
|
||||||
|
"project": "project"
|
||||||
|
"on-reload-epics": "onReloadEpics"
|
||||||
|
}, {
|
||||||
|
"project": @.project
|
||||||
|
"onReloadEpics": @_loadEpics
|
||||||
|
})
|
||||||
|
|
||||||
module.controller("EpicsDashboardCtrl", EpicsDashboardController)
|
module.controller("EpicsDashboardCtrl", EpicsDashboardController)
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
doctype html
|
|
||||||
|
|
||||||
.wrapper()
|
.wrapper()
|
||||||
tg-project-menu
|
tg-project-menu
|
||||||
section.main(role="main")
|
section.main(role="main")
|
||||||
|
@ -13,7 +11,7 @@ doctype html
|
||||||
button.button-green(
|
button.button-green(
|
||||||
translate="EPICS.DASHBOARD.ADD"
|
translate="EPICS.DASHBOARD.ADD"
|
||||||
title="{{ EPICS.DASHBOARD.ADD_TITLE | translate }}",
|
title="{{ EPICS.DASHBOARD.ADD_TITLE | translate }}",
|
||||||
ng-click="vm.addNewEpic()"
|
ng-click="vm.onCreateEpic()"
|
||||||
)
|
)
|
||||||
|
|
||||||
tg-epics-table(
|
tg-epics-table(
|
||||||
|
@ -37,6 +35,6 @@ doctype html
|
||||||
)
|
)
|
||||||
button.create-epic.button-green(
|
button.create-epic.button-green(
|
||||||
translate="EPICS.DASHBOARD.ADD"
|
translate="EPICS.DASHBOARD.ADD"
|
||||||
title="{{ EPICS.DASHBOARD.ADD_TITLE | translate }}",
|
title="{{ EPICS.DASHBOARD.ADD_TITLE | translate }}"
|
||||||
ng-click="vm.addNewEpic()"
|
ng-click="vm.onCreateEpic()"
|
||||||
)
|
)
|
||||||
|
|
|
@ -41,6 +41,11 @@ Resource = (urlsService, http) ->
|
||||||
|
|
||||||
return http.patch(url, patch)
|
return http.patch(url, patch)
|
||||||
|
|
||||||
|
service.post = (params) ->
|
||||||
|
url = urlsService.resolve("epics")
|
||||||
|
|
||||||
|
return http.post(url, params)
|
||||||
|
|
||||||
return () ->
|
return () ->
|
||||||
return {"epics": service}
|
return {"epics": service}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue