Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added link to sprint #223

Open
wants to merge 2 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions app/coffee/modules/common/lightboxes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1035,4 +1035,96 @@ module.directive("tgLbRelatetoepic", [
"$rootScope", "$tgConfirm", "lightboxService", "tgCurrentUserService", "tgResources",
"$tgResources", "tgEpicsService", "$tgAnalytics", RelateToEpicLightboxDirective])

#############################################################################
## RelateToSprint Lightbox Directive
#############################################################################

debounceLeading = @.taiga.debounceLeading

RelateToSprintLightboxDirective = ($rootScope, $confirm, lightboxService, $tgCurrentUserService
tgResources, $rs, tgAnalytics) ->
link = ($scope, $el, $attrs) ->
us = null

$scope.sprints = []
$scope.loading = false
$scope.selectedProject = $scope.project.id

params = {}
$rs.sprints.list($scope.selectedProject, params).then (result) ->
$scope.sprints = result.milestones

existingSprintForm = $el.find(".existing-sprint-form").checksley()

filterSprints = (selectedProjectId, filterText) ->
params = {}
$rs.sprints.list(selectedProjectId, params).then (result) ->
excludeId = $scope.us.milestone
searchText = filterText.toLowerCase()

filteredSprints = result.milestones.filter((sprint) ->
sprint.id != excludeId and (
sprint.slug.toLowerCase().includes(searchText) or
sprint.id.toString().includes(searchText)
)
)

$scope.sprints = filteredSprints

$el.on "click", ".close", (event) ->
event.preventDefault()
lightboxService.close($el)

$scope.$on "relate-to-sprint:add", (ctx, item) ->
us = item
$scope.selectedSprint = null
$scope.searchSprint = ""
filterSprints($scope.selectedProject, $scope.searchSprint).then () ->
lightboxService.open($el).then ->
$el.find('input').focus

$scope.$on "$destroy", ->
$el.off()

$scope.$on "related-sprint:changed", (ctx, userStory)->
$rs.userstories.getByRef(userStory.project, userStory.ref, {}).then((us) ->
$scope.us = us
return us
).then (us)->
$rs.sprints.get(us.project, us.milestone).then (sprint) =>
$scope.sprint = sprint

$scope.onUpdateSearchSprint = debounceLeading 300, () ->
$scope.selectedSprint = null
filterSprints($scope.selectedProject, $scope.searchSprint)

$scope.saveRelatedSprint = (selectedSprintId, onSavedRelatedSprint) ->
return if not existingSprintForm.validate()

$scope.loading = true

onError = (data) ->
$scope.loading = false
$confirm.notify("error")
existingSprintForm.setErrors(data)

onSuccess = (data) ->
$scope.loading = false
$scope.$broadcast("related-sprint:changed", us)
lightboxService.close($el)

bulk_data = [{
us_id: us.id
order: us.sprint_order
}]
$rs.userstories.bulkUpdateMilestone($scope.selectedProject, Number(selectedSprintId), bulk_data).then(
onSuccess, onError)

return {
templateUrl: "common/lightbox/lightbox-relate-to-sprint.html"
link:link
}

module.directive("tgLbRelatetosprint", [
"$rootScope", "$tgConfirm", "lightboxService", "tgCurrentUserService", "tgResources",
"$tgResources", "$tgAnalytics", RelateToSprintLightboxDirective])
3 changes: 3 additions & 0 deletions app/coffee/modules/userstories/detail.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.relateToEpic = (us) =>
@scope.$broadcast("relate-to-epic:add", us)

@scope.relateToSprint = (us) =>
@scope.$broadcast("relate-to-sprint:add", us)

@scope.$on "related-tasks:update", =>
@.loadTasks()
@scope.tasks = _.clone(@scope.tasks, false)
Expand Down
12 changes: 12 additions & 0 deletions app/locales/taiga/locale-en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,16 @@
"CHOOSE_EPIC": "What's the epic?",
"FILTER_EPICS": "Filter epics",
"NO_EPICS_FOUND": "It looks like nothing was found with your search criteria"
},
"RELATE_TO_SPRINT": {
"TITLE": "Link to sprint",
"EXISTING_SPRINT": "Existing sprint",
"CHOOSE_PROJECT_FOR_CREATION": "What's the project?",
"CHOOSE_PROJECT_FROM": "What's the project?",
"SUBJECT": "Subject",
"CHOOSE_SPRINT": "What's the sprint?",
"FILTER_SPRINTS": "Filter sprints",
"NO_SPRINTS_FOUND": "It looks like nothing was found with your search criteria"
}
},
"EPIC": {
Expand Down Expand Up @@ -1336,7 +1346,9 @@
"LIGHTBOX_TITLE_BLOKING_US": "Blocking user story",
"NOT_ESTIMATED": "N/E",
"OWNER_US": "This user story belongs to",
"OWNER_US_SPRINT": "This user story belongs to sprint",
"RELATE_TO_EPIC": "Link to epic",
"RELATE_TO_SPRINT": "Link to sprint",
"REMOVE_RELATIONSHIP_WITH_EPIC": "Remove epic relationship",
"TRIBE": {
"PUBLISH": "Publish as Gig in Taiga Tribe",
Expand Down
21 changes: 21 additions & 0 deletions app/modules/components/detail/header/detail-header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,27 @@
}
}
}
.relate-to-sprint {
flex-basis: 100%;
margin: 0 1rem .5rem 0;

.relate-to-sprint-button {
align-content: flex-end;
color: $color-link-primary;
cursor: pointer;
display: flex;
.icon-sprints {
fill: currentColor;
margin-right: .25rem;
}
.relate-to-sprint-text {
font-size: .9375rem;
}
}
}
.belong-to-sprint-title {
color: $color-black600;
}
& > .color-selector {
display: block;
margin-bottom: -2rem;
Expand Down
66 changes: 66 additions & 0 deletions app/partials/common/lightbox/lightbox-relate-to-sprint.jade
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

//- This source code is licensed under the terms of the
//- GNU Affero General Public License found in the LICENSE file in
//- the root directory of this source tree.
//-
//- Copyright (c) 2021-present Kaleidos INC

tg-lightbox-close

.lightbox-create-related-sprint-wrapper
h2.title(translate="LIGHTBOX.RELATE_TO_SPRINT.TITLE")

.button-group(tg-check-permission="modify_us")
.button-group-single
input(
type="radio"
name="related-with-selector"
id="existing-sprint"
value="existing-sprint"
ng-model="relatedWithSelector"
ng-init="relatedWithSelector='existing-sprint'"
)
label.e2e-existing-sprint-label(for="existing-sprint")
span.name {{ 'LIGHTBOX.RELATE_TO_SPRINT.EXISTING_SPRINT' | translate}}


fieldset.existing-sprint(ng-show="relatedWithSelector=='existing-sprint'")
label(
translate="LIGHTBOX.RELATE_TO_SPRINT.CHOOSE_SPRINT"
for="sprint-filter"
)
input.sprint-filter.e2e-filter-userstories-input(
id="sprint-filter"
type="text"
placeholder="{{'LIGHTBOX.RELATE_TO_SPRINT.FILTER_SPRINTS' | translate}}"
ng-model="searchSprint"
ng-change="onUpdateSearchSprint()"
)

form.existing-sprint-form(ng-show="relatedWithSelector=='existing-sprint' && sprints.length")
select.sprint.e2e-userstories-select(
size="5"
ng-model="selectedSprint"
data-required="true"
)
- var hash = "#";
option.hidden(
value=""
)
option(
ng-repeat="sprint in sprints track by sprint.id"
value="{{ ::sprint.id }}"
) #{hash}{{::sprint.id}} {{::sprint.name}}

p.no-stories-found(
ng-show="relatedWithSelector=='existing-sprint' && !sprints.length"
translate="LIGHTBOX.RELATE_TO_SPRINT.NO_SPRINTS_FOUND"
)

button.btn-big.e2e-select-related-sprint-button(
href=""
ng-click="saveRelatedSprint(selectedSprint, closeLightbox)"
tg-loading="loading"
translate="COMMON.SAVE"
)

26 changes: 26 additions & 0 deletions app/partials/us/us-detail.jade
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,31 @@ div.wrapper(
type="text"
)

.detail-header-line.belong-to-sprint-wrapper
.related-to-sprint
span.belong-to-sprint-title(ng-if="us.milestone", translate="US.OWNER_US_SPRINT")
a.belong-to-sprint-text(
href=""
tg-nav="project-taskboard:project=project.slug,sprint=sprint.slug"
ng-bind-html="'#'+us.milestone+' '+us.milestone_name | emojify"
)


//- User Story relate to Sprint
.relate-to-sprint(
tg-check-permission="modify_us"
)
a.relate-to-sprint-button.ng-animate-disabled(
href=""
title="{{'US.RELATE_TO_SPRINT' | translate}}"
ng-click="relateToSprint(us)"
)
//- tg-svg(
//- svg-icon="icon-add-to-sprint"
//- svg-title-translate="US.RELATE_TO_SPRINT"
//- )
span.relate-to-sprint-text(translate="US.RELATE_TO_SPRINT")

//- User Story belongs to epic
.detail-header-line.belong-to-epics-wrapper(ng-if="!!project.is_epics_activated")
.related-to-epics
Expand Down Expand Up @@ -215,3 +240,4 @@ div.wrapper(
ng-model="us"
)
div.lightbox.lightbox-relate-to-epic(tg-lb-relatetoepic)
div.lightbox.lightbox-relate-to-story(tg-lb-relatetosprint)