Relate to Epic button & lightbox
parent
0134ba0d26
commit
7ffa2ee292
|
@ -1122,4 +1122,120 @@ module.directive("tgLbCreateEdit", [
|
||||||
"$tgTemplate",
|
"$tgTemplate",
|
||||||
"$compile",
|
"$compile",
|
||||||
CreateEditDirective
|
CreateEditDirective
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## RelateToEpic Lightbox Directive
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
debounceLeading = @.taiga.debounceLeading
|
||||||
|
|
||||||
|
RelateToEpicLightboxDirective = ($rootScope, $confirm, lightboxService, tgCurrentUserService
|
||||||
|
tgResources, $tgResources, $epicsService, tgAnalytics) ->
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
us = null
|
||||||
|
|
||||||
|
$scope.projects = null
|
||||||
|
$scope.projectEpics = Immutable.List()
|
||||||
|
$scope.loading = false
|
||||||
|
|
||||||
|
newEpicForm = $el.find(".new-epic-form").checksley()
|
||||||
|
existingEpicForm = $el.find(".existing-epic-form").checksley()
|
||||||
|
|
||||||
|
loadProjects = ->
|
||||||
|
if $scope.projects == null
|
||||||
|
$tgResources.projects.list({
|
||||||
|
blocked_code: 'null',
|
||||||
|
is_epics_activated: true
|
||||||
|
}).then (data) ->
|
||||||
|
$scope.projects = data
|
||||||
|
|
||||||
|
filterEpics = (selectedProjectId, filterText) ->
|
||||||
|
tgResources.epics.listInAllProjects(
|
||||||
|
{
|
||||||
|
is_epics_activated: true,
|
||||||
|
project__blocked_code: 'null',
|
||||||
|
project: selectedProjectId,
|
||||||
|
q: filterText
|
||||||
|
}, true).then (data) ->
|
||||||
|
excludeIds = []
|
||||||
|
if (us.epics)
|
||||||
|
excludeIds = us.epics.map((epic) -> epic.id)
|
||||||
|
filteredData = data.filter((epic) -> excludeIds.indexOf(epic.get('id')) == -1)
|
||||||
|
$scope.projectEpics = filteredData
|
||||||
|
|
||||||
|
$el.on "click", ".close", (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
lightboxService.close($el)
|
||||||
|
|
||||||
|
$scope.$on "relate-to-epic:add", (ctx, item) ->
|
||||||
|
us = item
|
||||||
|
$scope.selectedEpic = null
|
||||||
|
$scope.searchEpic = ""
|
||||||
|
loadProjects()
|
||||||
|
filterEpics(item.projectId, $scope.searchEpic).then () ->
|
||||||
|
lightboxService.open($el).then ->
|
||||||
|
$el.find('input').focus
|
||||||
|
|
||||||
|
$scope.$on "$destroy", ->
|
||||||
|
$el.off()
|
||||||
|
|
||||||
|
$scope.onUpdateSearchEpic = debounceLeading 300, () ->
|
||||||
|
$scope.selectedEpic = null
|
||||||
|
filterEpics($scope.selectedProject, $scope.searchEpic)
|
||||||
|
|
||||||
|
$scope.saveRelatedEpic = (selectedEpicId, onSavedRelatedEpic) ->
|
||||||
|
return if not existingEpicForm.validate()
|
||||||
|
|
||||||
|
$scope.loading = true
|
||||||
|
|
||||||
|
onError = (data) ->
|
||||||
|
$scope.loading = false
|
||||||
|
$confirm.notify("error")
|
||||||
|
existingEpicForm.setErrors(data)
|
||||||
|
|
||||||
|
onSuccess = (data) ->
|
||||||
|
tgAnalytics.trackEvent(
|
||||||
|
"user story related epic", "create", "create related epic on user story", 1)
|
||||||
|
$scope.loading = false
|
||||||
|
$rootScope.$broadcast("related-epics:changed", us)
|
||||||
|
lightboxService.close($el)
|
||||||
|
|
||||||
|
usId = us.id
|
||||||
|
tgResources.epics.addRelatedUserstory(selectedEpicId, usId).then(
|
||||||
|
onSuccess, onError)
|
||||||
|
|
||||||
|
$scope.createEpic = (selectedProjectId, epicSubject) ->
|
||||||
|
return if not newEpicForm.validate()
|
||||||
|
|
||||||
|
@.loading = true
|
||||||
|
|
||||||
|
onError = (data)->
|
||||||
|
$scope.loading = false
|
||||||
|
$confirm.notify("error")
|
||||||
|
newEpicForm.setErrors(errors)
|
||||||
|
|
||||||
|
onSuccess = () ->
|
||||||
|
tgAnalytics.trackEvent(
|
||||||
|
"user story related epic", "create", "create related epic on user story", 1)
|
||||||
|
$scope.loading = false
|
||||||
|
$rootScope.$broadcast("related-epics:changed", us)
|
||||||
|
lightboxService.close($el)
|
||||||
|
|
||||||
|
onCreateEpic = (epic) ->
|
||||||
|
epicId = epic.get('id')
|
||||||
|
usId = us.id
|
||||||
|
tgResources.epics.addRelatedUserstory(epicId, usId).then(onSuccess, onError)
|
||||||
|
|
||||||
|
$epicsService.createEpic(
|
||||||
|
{subject: epicSubject}, null, selectedProjectId).then(onCreateEpic, onError)
|
||||||
|
|
||||||
|
return {
|
||||||
|
templateUrl: "common/lightbox/lightbox-relate-to-epic.html"
|
||||||
|
link:link
|
||||||
|
}
|
||||||
|
|
||||||
|
module.directive("tgLbRelatetoepic", [
|
||||||
|
"$rootScope", "$tgConfirm", "lightboxService", "tgCurrentUserService", "tgResources",
|
||||||
|
"$tgResources", "tgEpicsService", "$tgAnalytics", RelateToEpicLightboxDirective])
|
||||||
|
|
|
@ -36,8 +36,10 @@ resourceProvider = ($config, $repo, $http, $urls, $auth, $q, $translate) ->
|
||||||
service.getBySlug = (projectSlug) ->
|
service.getBySlug = (projectSlug) ->
|
||||||
return $repo.queryOne("projects", "by_slug?slug=#{projectSlug}")
|
return $repo.queryOne("projects", "by_slug?slug=#{projectSlug}")
|
||||||
|
|
||||||
service.list = ->
|
service.list = (filters) ->
|
||||||
return $repo.queryMany("projects")
|
params = {"order_by": "user_order"}
|
||||||
|
params = _.extend({}, params, filters or {})
|
||||||
|
return $repo.queryMany("projects", params)
|
||||||
|
|
||||||
service.listByMember = (memberId) ->
|
service.listByMember = (memberId) ->
|
||||||
params = {"member": memberId, "order_by": "user_order"}
|
params = {"member": memberId, "order_by": "user_order"}
|
||||||
|
|
|
@ -1127,6 +1127,10 @@
|
||||||
"DELETE_SPRINT": {
|
"DELETE_SPRINT": {
|
||||||
"TITLE": "Delete sprint"
|
"TITLE": "Delete sprint"
|
||||||
},
|
},
|
||||||
|
"REMOVE_RELATIONSHIP_WITH_EPIC": {
|
||||||
|
"TITLE": "Remove relationship with Epic",
|
||||||
|
"MESSAGE": "the relationship of this User Story with the Epic {{epicSubject}}"
|
||||||
|
},
|
||||||
"CREATE_MEMBER": {
|
"CREATE_MEMBER": {
|
||||||
"PLACEHOLDER_INVITATION_TEXT": "(Optional) Add a personalized text to the invitation. Tell something lovely to your new members ;-)",
|
"PLACEHOLDER_INVITATION_TEXT": "(Optional) Add a personalized text to the invitation. Tell something lovely to your new members ;-)",
|
||||||
"PLACEHOLDER_TYPE_EMAIL": "Type an Email",
|
"PLACEHOLDER_TYPE_EMAIL": "Type an Email",
|
||||||
|
@ -1167,6 +1171,18 @@
|
||||||
"IN_THREE_MONTHS": "In three months"
|
"IN_THREE_MONTHS": "In three months"
|
||||||
},
|
},
|
||||||
"TITLE_ACTION_DELETE_DUE_DATE": "Delete due date"
|
"TITLE_ACTION_DELETE_DUE_DATE": "Delete due date"
|
||||||
|
},
|
||||||
|
"RELATE_TO_EPIC": {
|
||||||
|
"TITLE": "Relate to Epic",
|
||||||
|
"EXISTING_EPIC": "Existing epic",
|
||||||
|
"NEW_EPIC": "New epic",
|
||||||
|
"CHOOSE_PROJECT_FOR_CREATION": "What's the project?",
|
||||||
|
"CHOOSE_PROJECT_FROM": "What's the project?",
|
||||||
|
"SUBJECT": "Subject",
|
||||||
|
"SUBJECT_BULK_MODE": "Subject (bulk insert)",
|
||||||
|
"CHOOSE_EPIC": "What's the epic?",
|
||||||
|
"FILTER_EPICS": "Filter epics",
|
||||||
|
"NO_EPICS_FOUND": "It looks like nothing was found with your search criteria"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EPIC": {
|
"EPIC": {
|
||||||
|
@ -1205,6 +1221,8 @@
|
||||||
"LIGHTBOX_TITLE_BLOKING_US": "Blocking us",
|
"LIGHTBOX_TITLE_BLOKING_US": "Blocking us",
|
||||||
"NOT_ESTIMATED": "Not estimated",
|
"NOT_ESTIMATED": "Not estimated",
|
||||||
"OWNER_US": "This User Story belongs to",
|
"OWNER_US": "This User Story belongs to",
|
||||||
|
"RELATE_TO_EPIC": "Relate to Epic",
|
||||||
|
"REMOVE_RELATIONSHIP_WITH_EPIC": "Remove Epic relationship",
|
||||||
"TRIBE": {
|
"TRIBE": {
|
||||||
"PUBLISH": "Publish as Gig in Taiga Tribe",
|
"PUBLISH": "Publish as Gig in Taiga Tribe",
|
||||||
"PUBLISH_INFO": "More info",
|
"PUBLISH_INFO": "More info",
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
- var hash = "#";
|
span(ng-if="epicsLength > 0", translate="US.OWNER_US")
|
||||||
span.belong-to-epic-text-wrapper(tg-repeat="epic in immutable_epics track by epic.get('id')")
|
span(ng-if="epicsLength > 1") :
|
||||||
a.belong-to-epic-text(
|
ul.belong-to-epics-list(ng-class="{'unique': epicsLength == 1 }")
|
||||||
href=""
|
li.belong-to-epic-text-wrapper(tg-repeat="epic in immutable_epics track by epic.get('id')")
|
||||||
tg-nav="project-epics-detail:project=epic.getIn(['project', 'slug']),ref=epic.get('ref')"
|
a.belong-to-epic-text(
|
||||||
ng-bind-html="'#'+epic.get('ref')+' '+epic.get('subject') | emojify"
|
href=""
|
||||||
)
|
tg-nav="project-epics-detail:project=epic.getIn(['project', 'slug']),ref=epic.get('ref')"
|
||||||
span.belong-to-epic-label(
|
ng-bind-html="'#'+epic.get('ref')+' '+epic.get('subject') | emojify"
|
||||||
ng-style="::{'background-color': epic.get('color')}"
|
)
|
||||||
translate="EPICS.EPIC"
|
span.belong-to-epic-label(
|
||||||
)
|
ng-style="::{'background-color': epic.get('color')}"
|
||||||
|
translate="EPICS.EPIC"
|
||||||
|
)
|
||||||
|
a.remove-epic-relationship(
|
||||||
|
title="{{'US.REMOVE_RELATIONSHIP_WITH_EPIC' | translate}}"
|
||||||
|
href=""
|
||||||
|
ng-click="removeEpicRelationship(epic)"
|
||||||
|
)
|
||||||
|
tg-svg(svg-icon="icon-close")
|
||||||
|
|
|
@ -19,12 +19,43 @@
|
||||||
|
|
||||||
module = angular.module('taigaEpics')
|
module = angular.module('taigaEpics')
|
||||||
|
|
||||||
BelongToEpicsDirective = () ->
|
BelongToEpicsDirective = ($translate, $confirm, $rs, $rs2, lightboxService) ->
|
||||||
|
|
||||||
link = (scope, el, attrs) ->
|
link = (scope, el, attrs) ->
|
||||||
scope.$watch 'epics', (epics) ->
|
scope.$watch 'epics', (epics) ->
|
||||||
|
updateEpics(epics)
|
||||||
|
|
||||||
|
scope.$on "related-epics:changed", (ctx, userStory)->
|
||||||
|
$rs.userstories.getByRef(userStory.project, userStory.ref, {}).then (us) ->
|
||||||
|
scope.item.epics = us.epics
|
||||||
|
updateEpics(us.epics)
|
||||||
|
|
||||||
|
scope.removeEpicRelationship = (epic) ->
|
||||||
|
title = $translate.instant("LIGHTBOX.REMOVE_RELATIONSHIP_WITH_EPIC.TITLE")
|
||||||
|
message = $translate.instant(
|
||||||
|
"LIGHTBOX.REMOVE_RELATIONSHIP_WITH_EPIC.MESSAGE",
|
||||||
|
{ epicSubject: epic.get('subject') }
|
||||||
|
)
|
||||||
|
|
||||||
|
$confirm.askOnDelete(title, message).then (askResponse) ->
|
||||||
|
onSuccess = ->
|
||||||
|
askResponse.finish()
|
||||||
|
scope.$broadcast("related-epics:changed", scope.item)
|
||||||
|
|
||||||
|
onError = ->
|
||||||
|
askResponse.finish(false)
|
||||||
|
$confirm.notify("error")
|
||||||
|
|
||||||
|
epicId = epic.get('id')
|
||||||
|
usId = scope.item.id
|
||||||
|
$rs2.epics.deleteRelatedUserstory(epicId, usId).then(onSuccess, onError)
|
||||||
|
|
||||||
|
updateEpics = (epics) ->
|
||||||
|
scope.epicsLength = 0
|
||||||
|
scope.immutable_epics = []
|
||||||
if epics && !epics.isIterable
|
if epics && !epics.isIterable
|
||||||
scope.immutable_epics = Immutable.fromJS(epics)
|
scope.epicsLength = epics.length
|
||||||
|
scope.immutable_epics = Immutable.fromJS(epics)
|
||||||
|
|
||||||
templateUrl = (el, attrs) ->
|
templateUrl = (el, attrs) ->
|
||||||
if attrs.format
|
if attrs.format
|
||||||
|
@ -34,10 +65,13 @@ BelongToEpicsDirective = () ->
|
||||||
return {
|
return {
|
||||||
link: link,
|
link: link,
|
||||||
scope: {
|
scope: {
|
||||||
epics: '='
|
epics: '=',
|
||||||
|
item: "="
|
||||||
},
|
},
|
||||||
templateUrl: templateUrl
|
templateUrl: templateUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.directive("tgBelongToEpics", BelongToEpicsDirective)
|
module.directive("tgBelongToEpics", [
|
||||||
|
"$translate", "$tgConfirm", "$tgResources", "tgResources", "lightboxService",
|
||||||
|
BelongToEpicsDirective])
|
||||||
|
|
|
@ -1,13 +1,57 @@
|
||||||
.belong-to-epic-pill-wrapper {
|
.belong-to-epic-pill-wrapper {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
&:hover {
|
&:hover .belong-to-epic-pill-data {
|
||||||
.belong-to-epic-pill-data {
|
display: block;
|
||||||
display: block;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.belong-to-epics-list {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
svg {
|
||||||
|
position: relative;
|
||||||
|
top: .1rem;
|
||||||
|
}
|
||||||
|
&.unique {
|
||||||
|
display: inline-block;
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
svg {
|
||||||
|
top: .2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.belong-to-epic-text-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-basis: 25%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding-top: .25rem;
|
||||||
|
.remove-epic-relationship {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: .5rem;
|
||||||
|
margin-left: .5rem;
|
||||||
|
svg {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover .remove-epic-relationship svg {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.belong-to-epic-label {
|
||||||
|
@include font-type(light);
|
||||||
|
@include font-size(xsmall);
|
||||||
|
background: $grayer;
|
||||||
|
border-radius: .25rem;
|
||||||
|
color: $white;
|
||||||
|
margin: 0 .5rem;
|
||||||
|
padding: .1rem .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.belong-to-epic-pill {
|
.belong-to-epic-pill {
|
||||||
background-color: $mass-white;
|
background-color: $mass-white;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
@ -17,20 +61,3 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
width: .7rem;
|
width: .7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.belong-to-epic-text-wrapper {
|
|
||||||
margin-right: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.belong-to-epic-text {
|
|
||||||
margin-left: .25rem;
|
|
||||||
}
|
|
||||||
.belong-to-epic-label {
|
|
||||||
@include font-type(light);
|
|
||||||
@include font-size(xsmall);
|
|
||||||
background: $grayer;
|
|
||||||
border-radius: .25rem;
|
|
||||||
color: $white;
|
|
||||||
margin: 0 .5rem;
|
|
||||||
padding: .1rem .25rem;
|
|
||||||
}
|
|
||||||
|
|
|
@ -92,4 +92,7 @@ class StoryHeaderController
|
||||||
return item
|
return item
|
||||||
return transform.then(onEditSubjectSuccess, onEditSubjectError)
|
return transform.then(onEditSubjectSuccess, onEditSubjectError)
|
||||||
|
|
||||||
|
relateToEpic: (us) ->
|
||||||
|
@rootScope.$broadcast("relate-to-epic:add", us)
|
||||||
|
|
||||||
module.controller("StoryHeaderCtrl", StoryHeaderController)
|
module.controller("StoryHeaderCtrl", StoryHeaderController)
|
||||||
|
|
|
@ -43,14 +43,26 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
//- User Story belongs to epic
|
//- User Story belongs to epic
|
||||||
.belong-to-epics-wrapper(ng-if="vm.item.epics")
|
.belong-to-epics-wrapper(ng-if="vm.item._name == 'userstories' && vm.project.is_epics_activated")
|
||||||
span(translate="US.OWNER_US")
|
.related-to-epics
|
||||||
tg-belong-to-epics(
|
tg-belong-to-epics(
|
||||||
ng-if="::vm.item.epics"
|
epics="::vm.item.epics"
|
||||||
epics="::vm.item.epics"
|
item="::vm.item"
|
||||||
format="text"
|
format="text"
|
||||||
|
)
|
||||||
|
//- User Story relate to Epic
|
||||||
|
a.relate-to-epic-button.ng-animate-disabled(
|
||||||
|
ng-if="vm.permissions.canEdit"
|
||||||
|
href=""
|
||||||
|
title="{{'US.RELATE_TO_EPIC' | translate}}"
|
||||||
|
ng-click="vm.relateToEpic(vm.item)"
|
||||||
)
|
)
|
||||||
|
tg-svg(
|
||||||
|
svg-icon="icon-epics"
|
||||||
|
svg-title-translate="US.RELATE_TO_EPIC"
|
||||||
|
)
|
||||||
|
span.relate-to-epic-text(translate="US.RELATE_TO_EPIC")
|
||||||
|
|
||||||
//- Task belongs to US
|
//- Task belongs to US
|
||||||
.task-belongs-to(
|
.task-belongs-to(
|
||||||
ng-if="vm.item.user_story_extra_info"
|
ng-if="vm.item.user_story_extra_info"
|
||||||
|
|
|
@ -30,6 +30,22 @@
|
||||||
@include font-size(small);
|
@include font-size(small);
|
||||||
margin-top: .5rem;
|
margin-top: .5rem;
|
||||||
}
|
}
|
||||||
|
.relate-to-epic-button {
|
||||||
|
color: $gray-light;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
&:hover {
|
||||||
|
color: $primary-light;
|
||||||
|
}
|
||||||
|
.icon-epics {
|
||||||
|
@include svg-size(.9rem);
|
||||||
|
fill: currentColor;
|
||||||
|
margin: .5rem .25rem 0 0;
|
||||||
|
}
|
||||||
|
.relate-to-epic-text {
|
||||||
|
@include font-size(small);
|
||||||
|
}
|
||||||
|
}
|
||||||
.item-generated-us,
|
.item-generated-us,
|
||||||
.task-belongs-to,
|
.task-belongs-to,
|
||||||
.item-origin-issue,
|
.item-origin-issue,
|
||||||
|
|
|
@ -64,15 +64,23 @@ class EpicsService
|
||||||
listRelatedUserStories: (epic) ->
|
listRelatedUserStories: (epic) ->
|
||||||
return @resources.userstories.listInEpic(epic.get('id'))
|
return @resources.userstories.listInEpic(epic.get('id'))
|
||||||
|
|
||||||
createEpic: (epicData, attachments) ->
|
createEpic: (epicData, attachments, projectId) ->
|
||||||
epicData.project = @projectService.project.get('id')
|
if projectId
|
||||||
|
epicData.project = projectId
|
||||||
|
else
|
||||||
|
epicData.project = @projectService.project.get('id')
|
||||||
|
|
||||||
return @resources.epics.post(epicData)
|
return @resources.epics.post(epicData)
|
||||||
.then (epic) =>
|
.then (epic) =>
|
||||||
promises = _.map attachments.toJS(), (attachment) =>
|
if !attachments
|
||||||
@attachmentsService.upload(attachment.file, epic.get('id'), epic.get('project'), 'epic')
|
return epic
|
||||||
|
else
|
||||||
|
promises = _.map attachments.toJS(), (attachment) =>
|
||||||
|
@attachmentsService.upload(
|
||||||
|
attachment.file, epic.get('id'), epic.get('project'), 'epic')
|
||||||
|
|
||||||
|
Promise.all(promises).then(@.fetchEpics.bind(this, true))
|
||||||
|
|
||||||
Promise.all(promises).then(@.fetchEpics.bind(this, true))
|
|
||||||
|
|
||||||
reorderEpic: (epic, newIndex) ->
|
reorderEpic: (epic, newIndex) ->
|
||||||
orderList = {}
|
orderList = {}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
tg-lightbox-close
|
||||||
|
|
||||||
|
.lightbox-create-related-epic-wrapper
|
||||||
|
h2.title(translate="LIGHTBOX.RELATE_TO_EPIC.TITLE")
|
||||||
|
|
||||||
|
.related-with-selector(tg-check-permission="add_epic")
|
||||||
|
.related-with-selector-single
|
||||||
|
input(
|
||||||
|
type="radio"
|
||||||
|
name="related-with-selector"
|
||||||
|
id="existing-epic"
|
||||||
|
value="existing-epic"
|
||||||
|
ng-model="relatedWithSelector"
|
||||||
|
ng-init="relatedWithSelector='existing-epic'"
|
||||||
|
)
|
||||||
|
label.e2e-existing-epic-label(for="existing-epic")
|
||||||
|
span.name {{ 'LIGHTBOX.RELATE_TO_EPIC.EXISTING_EPIC' | translate}}
|
||||||
|
|
||||||
|
.related-with-selector-single
|
||||||
|
input(
|
||||||
|
type="radio"
|
||||||
|
name="related-with-selector"
|
||||||
|
id="new-epic"
|
||||||
|
value="new-epic"
|
||||||
|
ng-model="relatedWithSelector"
|
||||||
|
)
|
||||||
|
label.e2e-new-epic-label(for="new-epic")
|
||||||
|
span.name {{ 'LIGHTBOX.RELATE_TO_EPIC.NEW_EPIC' | translate}}
|
||||||
|
|
||||||
|
fieldset.project-selector
|
||||||
|
label(
|
||||||
|
ng-if="relatedWithSelector=='new-epic'"
|
||||||
|
translate="LIGHTBOX.RELATE_TO_EPIC.CHOOSE_PROJECT_FOR_CREATION"
|
||||||
|
for="project-selector-dropdown"
|
||||||
|
)
|
||||||
|
label(
|
||||||
|
ng-if="relatedWithSelector=='existing-epic'"
|
||||||
|
translate="LIGHTBOX.RELATE_TO_EPIC.CHOOSE_PROJECT_FROM"
|
||||||
|
for="project-selector-dropdown"
|
||||||
|
)
|
||||||
|
select(
|
||||||
|
ng-model="selectedProject"
|
||||||
|
ng-change="selectProject(selectedProject)"
|
||||||
|
data-required="true"
|
||||||
|
ng-options="p.id as p.name for p in projects | toMutable"
|
||||||
|
id="project-selector-dropdown"
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldset(ng-show="relatedWithSelector=='new-epic'")
|
||||||
|
.new-epic-title
|
||||||
|
label(translate="LIGHTBOX.RELATE_TO_EPIC.SUBJECT")
|
||||||
|
form.new-epic-form
|
||||||
|
.single-creation
|
||||||
|
input.e2e-new-epic-input-text(
|
||||||
|
type="text"
|
||||||
|
ng-model="epicSubject"
|
||||||
|
data-required="true"
|
||||||
|
)
|
||||||
|
|
||||||
|
button.button-green.create-epic.e2e-create-epic-button.ng-animate-disabled(
|
||||||
|
href=""
|
||||||
|
ng-click="createEpic(selectedProject, epicSubject)"
|
||||||
|
tg-loading="loading"
|
||||||
|
translate="COMMON.SAVE"
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldset.existing-epic(ng-show="relatedWithSelector=='existing-epic'")
|
||||||
|
label(
|
||||||
|
translate="LIGHTBOX.RELATE_TO_EPIC.CHOOSE_EPIC"
|
||||||
|
for="epic-filter"
|
||||||
|
)
|
||||||
|
input.epic-filter.e2e-filter-userstories-input(
|
||||||
|
id="epic-filter"
|
||||||
|
type="text"
|
||||||
|
placeholder="{{'LIGHTBOX.RELATE_TO_EPIC.FILTER_EPICS' | translate}}"
|
||||||
|
ng-model="searchEpic"
|
||||||
|
ng-change="onUpdateSearchEpic()"
|
||||||
|
)
|
||||||
|
|
||||||
|
form.existing-epic-form(ng-show="relatedWithSelector=='existing-epic' && projectEpics.size")
|
||||||
|
select.epic.e2e-userstories-select(
|
||||||
|
size="5"
|
||||||
|
ng-model="selectedEpic"
|
||||||
|
data-required="true"
|
||||||
|
)
|
||||||
|
- var hash = "#";
|
||||||
|
option.hidden(
|
||||||
|
value=""
|
||||||
|
)
|
||||||
|
option(
|
||||||
|
ng-repeat="epic in projectEpics | toMutable track by epic.id"
|
||||||
|
value="{{ ::epic.id }}"
|
||||||
|
) #{hash}{{::epic.ref}} {{::epic.subject}}
|
||||||
|
|
||||||
|
p.no-stories-found(
|
||||||
|
ng-show="relatedWithSelector=='existing-epic' && !projectEpics.size"
|
||||||
|
translate="LIGHTBOX.RELATE_TO_EPIC.NO_EPICS_FOUND"
|
||||||
|
)
|
||||||
|
|
||||||
|
button.button-green.e2e-select-related-epic-button(
|
||||||
|
href=""
|
||||||
|
ng-click="saveRelatedEpic(selectedEpic, closeLightbox)"
|
||||||
|
tg-loading="loading"
|
||||||
|
translate="COMMON.SAVE"
|
||||||
|
)
|
||||||
|
|
|
@ -156,3 +156,4 @@ div.wrapper(
|
||||||
div.lightbox.lightbox-select-user(tg-lb-assignedto)
|
div.lightbox.lightbox-select-user(tg-lb-assignedto)
|
||||||
div.lightbox.lightbox-select-user(tg-lb-assigned-users)
|
div.lightbox.lightbox-select-user(tg-lb-assigned-users)
|
||||||
div.lightbox.lightbox-select-user(tg-lb-watchers)
|
div.lightbox.lightbox-select-user(tg-lb-watchers)
|
||||||
|
div.lightbox.lightbox-relate-to-epic(tg-lb-relatetoepic)
|
||||||
|
|
|
@ -854,7 +854,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.ticket-detail-settings .lightbox-assign-sprint-to-issue {
|
.ticket-detail-settings .lightbox-assign-sprint-to-issue {
|
||||||
.lightbox-assign-related-sprint {
|
.lightbox-assign-related-sprint {
|
||||||
width: 700px;
|
width: 700px;
|
||||||
|
@ -883,6 +882,92 @@
|
||||||
button {
|
button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.lightbox-relate-to-epic {
|
||||||
|
.lightbox-create-related-epic-wrapper {
|
||||||
|
max-width: 600px;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
.related-with-selector {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
&:checked+label {
|
||||||
|
background: $primary-light;
|
||||||
|
color: $white;
|
||||||
|
transition: background .2s ease-in;
|
||||||
|
}
|
||||||
|
&:checked+label:hover {
|
||||||
|
background: $primary-light;
|
||||||
|
}
|
||||||
|
+label {
|
||||||
|
background: rgba($whitish, .7);
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: background .2s ease-in;
|
||||||
|
}
|
||||||
|
+label:hover {
|
||||||
|
background: rgba($primary-light, .3);
|
||||||
|
transition: background .2s ease-in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.related-with-selector-single {
|
||||||
|
flex: 1;
|
||||||
|
&:first-child {
|
||||||
|
margin-right: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldset {
|
||||||
|
label {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.new-epic-title {
|
||||||
|
align-items: flex-end;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.existing-epic-form,
|
||||||
|
.new-epic-form {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.no-epics-found {
|
||||||
|
padding: 1rem 0 0;
|
||||||
|
}
|
||||||
|
.new-epic-options {
|
||||||
|
display: flex;
|
||||||
|
margin-left: auto;
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
&:checked+label {
|
||||||
|
background: $primary-light;
|
||||||
|
color: $white;
|
||||||
|
fill: $white;
|
||||||
|
transition: background .2s ease-in;
|
||||||
|
}
|
||||||
|
+label {
|
||||||
|
background: $mass-white;
|
||||||
|
color: $grayer;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
padding: .5rem;
|
||||||
|
transition: background .2s ease-in;
|
||||||
|
}
|
||||||
|
+label:hover {
|
||||||
|
background: $primary-light;
|
||||||
|
color: $white;
|
||||||
|
fill: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue