diff --git a/app/locales/taiga/locale-en.json b/app/locales/taiga/locale-en.json index 3d8eff98..dc285a85 100644 --- a/app/locales/taiga/locale-en.json +++ b/app/locales/taiga/locale-en.json @@ -412,6 +412,14 @@ "STATUS": "Status", "PROGRESS": "Progress", "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": { diff --git a/app/modules/epics/create-epic/create-epic.controller.coffee b/app/modules/epics/create-epic/create-epic.controller.coffee new file mode 100644 index 00000000..ea0f1b3e --- /dev/null +++ b/app/modules/epics/create-epic/create-epic.controller.coffee @@ -0,0 +1,38 @@ +### +# Copyright (C) 2014-2015 Taiga Agile LLC +# +# 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 . +# +# 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) diff --git a/app/modules/epics/create-epic/create-epic.directive.coffee b/app/modules/epics/create-epic/create-epic.directive.coffee new file mode 100644 index 00000000..6fd7883a --- /dev/null +++ b/app/modules/epics/create-epic/create-epic.directive.coffee @@ -0,0 +1,37 @@ +### +# Copyright (C) 2014-2016 Taiga Agile LLC +# +# 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 . +# +# 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) diff --git a/app/modules/epics/create-epic/create-epic.jade b/app/modules/epics/create-epic/create-epic.jade new file mode 100644 index 00000000..645ca696 --- /dev/null +++ b/app/modules/epics/create-epic/create-epic.jade @@ -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" + ) + diff --git a/app/modules/epics/create-epic/create-epic.scss b/app/modules/epics/create-epic/create-epic.scss new file mode 100644 index 00000000..ad2090c4 --- /dev/null +++ b/app/modules/epics/create-epic/create-epic.scss @@ -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%; + } +} diff --git a/app/modules/epics/dashboard/epic-row/epic-row.controller.coffee b/app/modules/epics/dashboard/epic-row/epic-row.controller.coffee index 221d6088..ba338e5b 100644 --- a/app/modules/epics/dashboard/epic-row/epic-row.controller.coffee +++ b/app/modules/epics/dashboard/epic-row/epic-row.controller.coffee @@ -28,6 +28,7 @@ class EpicRowController constructor: (@rs, @confirm) -> @.displayUserStories = false @._calculateProgressBar() + @.displayAssignedTo = false _calculateProgressBar: () -> totalUs = @.epic.getIn(['user_stories_counts', 'closed']) @@ -67,6 +68,6 @@ class EpicRowController @.displayUserStories = false onSelectAssignedTo: () -> - console.log 'onSelectAssignedTo' + console.log 'Assigned to' module.controller("EpicRowCtrl", EpicRowController) diff --git a/app/modules/epics/dashboard/epics-dashboard.controller.coffee b/app/modules/epics/dashboard/epics-dashboard.controller.coffee index 477c288e..90066000 100644 --- a/app/modules/epics/dashboard/epics-dashboard.controller.coffee +++ b/app/modules/epics/dashboard/epics-dashboard.controller.coffee @@ -24,12 +24,14 @@ class EpicsDashboardController "$tgResources", "tgResources", "$routeParams", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgLightboxFactory", ] - constructor: (@rs, @resources, @params, @errorHandlingService) -> + constructor: (@rs, @resources, @params, @errorHandlingService, @lightboxFactory) -> @.sectionName = "Epics" @._loadProject() + @.createEpic = false _loadProject: () -> return @rs.projects.getBySlug(@params.pslug).then (project) => @@ -43,7 +45,14 @@ class EpicsDashboardController return @resources.epics.list(projectId).then (epics) => @.epics = epics - addNewEpic: () -> - console.log 'Add new Epic' + onCreateEpic: () -> + @lightboxFactory.create('tg-create-epic', { + "class": "lightbox lightbox-create-epic" + "project": "project" + "on-reload-epics": "onReloadEpics" + }, { + "project": @.project + "onReloadEpics": @_loadEpics + }) module.controller("EpicsDashboardCtrl", EpicsDashboardController) diff --git a/app/modules/epics/dashboard/epics-dashboard.jade b/app/modules/epics/dashboard/epics-dashboard.jade index 788cbdce..c2f22f05 100644 --- a/app/modules/epics/dashboard/epics-dashboard.jade +++ b/app/modules/epics/dashboard/epics-dashboard.jade @@ -1,5 +1,3 @@ -doctype html - .wrapper() tg-project-menu section.main(role="main") @@ -13,7 +11,7 @@ doctype html button.button-green( translate="EPICS.DASHBOARD.ADD" title="{{ EPICS.DASHBOARD.ADD_TITLE | translate }}", - ng-click="vm.addNewEpic()" + ng-click="vm.onCreateEpic()" ) tg-epics-table( @@ -37,6 +35,6 @@ doctype html ) button.create-epic.button-green( translate="EPICS.DASHBOARD.ADD" - title="{{ EPICS.DASHBOARD.ADD_TITLE | translate }}", - ng-click="vm.addNewEpic()" + title="{{ EPICS.DASHBOARD.ADD_TITLE | translate }}" + ng-click="vm.onCreateEpic()" ) diff --git a/app/modules/resources/epics-resource.service.coffee b/app/modules/resources/epics-resource.service.coffee index ddc4fe40..ed06dcb9 100644 --- a/app/modules/resources/epics-resource.service.coffee +++ b/app/modules/resources/epics-resource.service.coffee @@ -41,6 +41,11 @@ Resource = (urlsService, http) -> return http.patch(url, patch) + service.post = (params) -> + url = urlsService.resolve("epics") + + return http.post(url, params) + return () -> return {"epics": service}