Assigned Users frontend functionality

stable
Álex Hermida 2018-02-20 07:45:27 +01:00
parent cea62718b3
commit 3ec018037d
12 changed files with 309 additions and 34 deletions

View File

@ -292,7 +292,6 @@ class QueueModelTransformation extends taiga.Service
save: (transformation) ->
defered = @q.defer()
@qqueue.add () =>
obj = @.getObj()
comment = obj.comment

View File

@ -230,7 +230,6 @@ WatchersDirective = ($rootscope, $confirm, $repo, $modelTransform, $template, $c
watchers = _.map(watchers, (watcherId) -> $scope.usersById[watcherId])
renderWatchers(watchers)
$rootscope.$broadcast("object:updated")
transform.then null, ->
$confirm.notify("error")
@ -304,7 +303,7 @@ module.directive("tgWatchers", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgQueue
## Assigned Users directive
#############################################################################
AssignedUsersDirective = ($rootscope, $confirm, $repo, $modelTransform, $template, $compile, $translate) ->
AssignedUsersDirective = ($rootscope, $confirm, $repo, $modelTransform, $template, $compile, $translate, $currentUserService) ->
# You have to include a div with the tg-lb-assignedusers directive in the page
# where use this directive
@ -314,27 +313,42 @@ AssignedUsersDirective = ($rootscope, $confirm, $repo, $modelTransform, $templat
isAssigned = ->
return $scope.assignedUsers.length > 0
save = (assignedUsers) ->
save = (assignedUsers, assignedToUser) ->
transform = $modelTransform.save (item) ->
item.assignedUsers = assignedUsers
item.assigned_users = assignedUsers
if not item.assigned_to
item.assigned_to = assignedToUser
return item
transform.then ->
console.log(assignedUserId)
assignedUsers = _.map(assignedUsers, (assignedUserId) -> $scope.usersById[assignedUserId])
renderAssignedUsers(assignedUsers)
$rootscope.$broadcast("object:updated")
result = $rootscope.$broadcast("object:updated")
transform.then null, ->
$confirm.notify("error")
openAssignedUsers = ->
item = _.clone($model.$modelValue, false)
$rootscope.$broadcast("assignedUser:add", item)
$rootscope.$broadcast("assigned-user:add", item)
assignToMe = ->
return if not isEditable()
currentUserId = $currentUserService.getUser().get('id')
assignedUsers = _.clone($model.$modelValue.assigned_users, false)
assignedUsers.push(currentUserId)
assignedUsers = _.uniq(assignedUsers)
save(assignedUsers, currentUserId)
deleteAssignedUser = (assignedUserIds) ->
transform = $modelTransform.save (item) ->
item.assignedUsers = assignedUserIds
item.assigned_users = assignedUserIds
# Update as
if item.assigned_to not in assignedUserIds and assignedUserIds.length > 0
item.assigned_to = assignedUserIds[0]
if assignedUserIds.length == 0
item.assigned_to = null
return item
@ -353,32 +367,32 @@ AssignedUsersDirective = ($rootscope, $confirm, $repo, $modelTransform, $templat
$scope.isEditable = isEditable()
$scope.isAssigned = isAssigned()
$scope.openAssignedUsers = openAssignedUsers
console.log('rendering...')
$scope.assignToMe = assignToMe
$el.on "click", ".js-delete-watcher", (event) ->
$el.on "click", ".remove-user", (event) ->
event.preventDefault()
return if not isEditable()
target = angular.element(event.currentTarget)
watcherId = target.data("watcher-id")
assignedUserId = target.data("assigned-user-id")
title = $translate.instant("COMMON.WATCHERS.TITLE_LIGHTBOX_DELETE_WARTCHER")
message = $scope.usersById[watcherId].full_name_display
title = $translate.instant("COMMON.ASSIGNED_USERS.TITLE_LIGHTBOX_DELETE_ASSIGNED")
message = $scope.usersById[assignedUserId].full_name_display
$confirm.askOnDelete(title, message).then (askResponse) =>
askResponse.finish()
watcherIds = _.clone($model.$modelValue.watchers, false)
watcherIds = _.pull(watcherIds, watcherId)
assignedUserIds = _.clone($model.$modelValue.assigned_users, false)
assignedUserIds = _.pull(assignedUserIds, assignedUserId)
deleteWatcher(watcherIds)
$scope.$on "assignedUser:added", (ctx, assignedUserId) ->
deleteAssignedUser(assignedUserIds)
$scope.$on "assigned-user:added", (ctx, assignedUserId) ->
assignedUsers = _.clone($model.$modelValue.assigned_users, false)
assignedUsers.push(assignedUserId)
assignedUsers = _.uniq(assignedUsers)
save(assignedUsers)
# Save assigned_users and assignedUserId for assign_to legacy attribute
save(assignedUsers, assignedUserId)
$scope.$watch $attrs.ngModel, (item) ->
return if not item?
@ -398,7 +412,7 @@ AssignedUsersDirective = ($rootscope, $confirm, $repo, $modelTransform, $templat
}
module.directive("tgAssignedUsers", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgQueueModelTransformation", "$tgTemplate", "$compile",
"$translate", AssignedUsersDirective])
"$translate", "tgCurrentUserService", AssignedUsersDirective])
#############################################################################
@ -488,7 +502,6 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $modelTransform, $
$scope.$on "assigned-to:added", (ctx, userId, item) ->
return if item.id != $model.$modelValue.id
save(userId)
$scope.$watch $attrs.ngModel, (instance) ->

View File

@ -646,7 +646,6 @@ AssignedToLightboxDirective = (lightboxService, lightboxKeyboardNavigationServic
selectedItem = item
assignedToId = item.assigned_to
selectedUser = $scope.usersById[assignedToId]
render(selectedUser)
lightboxService.open($el).then ->
$el.find('input').focus()
@ -706,10 +705,10 @@ AssignedUsersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNaviga
usersTemplate = $template.get("common/lightbox/lightbox-assigned-to-users.html", true)
# Get prefiltered users by text
# and without now watched users.
# and without now assigned users.
getFilteredUsers = (text="") ->
_filterUsers = (text, user) ->
if selectedItem && _.find(selectedItem.assignedUsers, (x) -> x == user.id)
if selectedItem && _.find(selectedItem.assigned_users, (x) -> x == user.id)
return false
username = user.full_name_display.toUpperCase()
@ -737,16 +736,14 @@ AssignedUsersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNaviga
html = usersTemplate(ctx)
html = $compile(html)($scope)
$el.find(".ticket-watchers").html(html)
$el.find(".assigned-to-list").html(html)
closeLightbox = () ->
lightboxKeyboardNavigationService.stop()
lightboxService.close($el)
$scope.$on "assignedUser:add", (ctx, item) ->
console.log(item)
$scope.$on "assigned-user:add", (ctx, item) ->
selectedItem = item
users = getFilteredUsers()
render(users)
@ -770,7 +767,7 @@ AssignedUsersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNaviga
$scope.$apply ->
$scope.usersSearch = null
$scope.$broadcast("assignedUser:added", target.data("user-id"))
$scope.$broadcast("assigned-user:added", target.data("user-id"), selectedItem)
$el.on "click", ".close", (event) ->
event.preventDefault()
@ -784,7 +781,7 @@ AssignedUsersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNaviga
$el.off()
return {
templateUrl: "common/lightbox/lightbox-users.html"
templateUrl: "common/lightbox/lightbox-assigned-users.html"
link:link
}

View File

@ -152,6 +152,7 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@kanbanUserstoriesService.replaceModel(us)
@scope.$on("assigned-to:added", @.onAssignedToChanged)
@scope.$on("assigned-user:added", @.onAssignedUsersChanged)
@scope.$on("kanban:us:move", @.moveUs)
@scope.$on("kanban:show-userstories-for-status", @.loadUserStoriesForStatus)
@scope.$on("kanban:hide-userstories-for-status", @.hideUserStoriesForStatus)
@ -194,6 +195,10 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@rootscope.$broadcast("assigned-to:add", us)
changeUsAssignedUsers: (id) ->
us = @kanbanUserstoriesService.getUsModel(id)
@rootscope.$broadcast("assigned-user:add", us)
onAssignedToChanged: (ctx, userid, usModel) ->
usModel.assigned_to = userid
@ -204,6 +209,20 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
if @.isFilterDataTypeSelected('assigned_to') || @.isFilterDataTypeSelected('role')
@.filtersReloadContent()
onAssignedUsersChanged: (ctx, userid, usModel) ->
assignedUsers = _.clone(usModel.assigned_users, false)
assignedUsers.push(userid)
assignedUsers = _.uniq(assignedUsers)
usModel.assigned_users = assignedUsers
if not usModel.assigned_to
usModel.assigned_to = userid
@kanbanUserstoriesService.replaceModel(usModel)
promise = @repo.save(usModel)
promise.then null, ->
console.log "FAIL" # TODO
refreshTagsColors: ->
return @rs.projects.tagsColors(@scope.projectId).then (tags_colors) =>
@scope.project.tags_colors = tags_colors._attrs

View File

@ -170,6 +170,11 @@
"PAST_DUE": "past due",
"NO_LONGER_APPLICABLE": "no longer applicable"
},
"ASSIGNED_USERS": {
"ADD": "Select assigned user",
"ADD_ASSIGNED": "Add assigned",
"TITLE_LIGHTBOX_DELETE_ASSIGNED": "Delete assigned..."
},
"STATUS": {
"CLOSED": "Closed",
"OPEN": "Open"

View File

@ -0,0 +1,62 @@
.assigned-title(ng-if="!isAssigned") {{ "COMMON.ASSIGNED_TO.NOT_ASSIGNED" | translate }}
.assigned-title(ng-if="isAssigned") {{ "COMMON.FIELDS.ASSIGNED_TO" | translate }}
.tg-assigned-users
.not-assigned-users(ng-if="!isAssigned")
.user-avatar(ng-class="{'is-iocaine': isIocaine}")
img(
tg-avatar=""
alt="{{ 'COMMON.ASSIGNED_TO.ASSIGN' | translate }}"
)
//- .iocaine-symbol(ng-if="isIocaine" title="{{ 'TASK.TITLE_ACTION_IOCAINE' | translate }}")
//- tg-svg(svg-icon="icon-iocaine")
.assigned-to
.assigned-users-options
a(
href=""
title="{{ 'COMMON.ASSIGNED_TO.TITLE_ACTION_EDIT_ASSIGNMENT'|translate }}"
class="user-assigned"
ng-class="{editable: isEditable}"
ng-click="openAssignedUsers()"
)
span.assigned-name {{ "COMMON.ASSIGNED_TO.ASSIGN" | translate }}
span(translate="COMMON.OR")
|  
a.assign-to-me(
href="#"
title="{{'COMMON.ASSIGNED_TO.SELF' | translate}}"
ng-click="assignToMe()"
)
span {{ "COMMON.ASSIGNED_TO.SELF" | translate }}
.user-list-single(ng-repeat="assignedUser in assignedUsers")
.user-list-avatar
img(
tg-avatar="assignedUser"
alt="{{assignedUser.full_name_display}}"
)
.user-list-name.assigned-users-options
a(
href=""
title="{{ 'COMMON.ASSIGNED_TO.TITLE_ACTION_EDIT_ASSIGNMENT'|translate }}"
class!="user-assigned <% if (isEditable) { %>editable<% }; %>"
)
span.assigned-name {{assignedUser.full_name_display}}
tg-svg.remove-user(
ng-if="isEditable",
data-assigned-user-id="{{assignedUser.id}}"
svg-icon="icon-close",
title="{{'COMMON.ASSIGNED_TO.DELETE_ASSIGNMENT' | translate}}"
)
.tg-add-assigned(ng-if="isAssigned")
tg-svg.add-assigned(
ng-if="isEditable",
data-assigned-user-id="{{assignedUser.id}}",
ng-click="openAssignedUsers()",
svg-icon="icon-add",
title="{{'COMMON.ASSIGNED_USERS.ADD_ASSIGNED' | translate}}"
)
span {{ "COMMON.ASSIGNED_USERS.ADD_ASSIGNED" | translate }}

View File

@ -0,0 +1,8 @@
tg-lightbox-close
div.form
h2.title(translate="COMMON.ASSIGNED_USERS.ADD")
fieldset
input(type="text", data-maxlength="500", placeholder="{{'LIGHTBOX.ASSIGNED_TO.SEARCH' | translate}}", ng-model="usersSearch")
div.assigned-to-list
//- The content of this is rendered by directive

View File

@ -80,7 +80,7 @@ div.kanban-table(
tg-bind-scope,
on-toggle-fold="ctrl.toggleFold(id)"
on-click-edit="ctrl.editUs(id)"
on-click-assigned-to="ctrl.changeUsAssignedTo(id)"
on-click-assigned-to="ctrl.changeUsAssignedUsers(id)"
project="project"
item="us"
zoom="ctrl.zoom"

View File

@ -46,4 +46,4 @@ div.wrapper(
div.lightbox.lightbox-generic-bulk(tg-lb-create-bulk-userstories)
include ../includes/modules/lightbox-us-bulk
div.lightbox.lightbox-select-user(tg-lb-assignedto)
div.lightbox.lightbox-select-user(tg-lb-assigned-users)

View File

@ -95,6 +95,7 @@ div.wrapper(
tg-us-estimation.ticket-estimation(ng-model="us")
#TODELETE
section.ticket-assigned-to(
tg-assigned-to
ng-model="us"

View File

@ -92,3 +92,35 @@
}
}
}
.ticket-assigned-users {
@include user-list;
margin-top: 1rem;
.user-list-single {
flex-grow: 1;
&:hover {
.remove-user {
opacity: 1;
transition: opacity .2s ease-in;
}
}
}
.user-list-name {
@include font-type(text);
flex: 1;
position: relative;
}
.remove-user {
cursor: pointer;
fill: currentColor;
opacity: 0;
position: absolute;
right: .5rem;
top: 0;
transition: all .2s ease-in;
&:hover {
fill: $red;
transition: color .3s ease-in;
}
}
}

View File

@ -0,0 +1,139 @@
.ticket-assigned-users {
align-items: center;
border-bottom: 1px solid $gray-light;
border-top: 1px solid $gray-light;
margin-bottom: 1rem;
padding: .5rem 0;
position: relative;
.loading-spinner {
@include loading-spinner;
margin: 1rem auto;
max-height: 2rem;
max-width: 2rem;
}
.assigned-title {
@include font-size(small);
@include font-type(light);
color: $gray;
display: block;
margin: .2rem 0 .25rem;
}
.tg-assigned-users {
align-items: center;
position: relative;
}
.tg-add-assigned {
margin-top: .25rem;
.add-assigned {
fill: $gray;
opacity: 1;
right: .5rem;
top: 2rem;
&:hover {
cursor: pointer;
fill: $red;
transition: fill .2s;
}
}
span {
@include font-size(small);
@include font-type(light);
color: $gray;
margin: .2rem .5rem;
}
}
.assigned-users-options {
align-content: center;
display: flex;
a {
margin-right: .2rem;
}
}
.user-assigned,
.assign-to-me {
color: $primary;
&.editable {
color: $primary;
&:hover {
cursor: pointer;
}
}
.icon {
vertical-align: middle;
}
}
.not-assigned-users {
align-items: center;
display: flex;
.assigned-title {
@include font-size(small);
@include font-type(light);
color: $gray;
display: block;
margin: .2rem 0 .25rem;
}
.assigned-to {
flex-grow: 1;
margin-left: .5rem;
}
.assigned-to-options {
align-content: center;
display: flex;
a {
margin-right: .2rem;
}
}
.user-assigned,
.assign-to-me {
color: $primary;
cursor: default;
&:hover {
cursor: pointer;
}
.icon {
fill: currentColor;
height: .75rem;
width: .75rem;
}
}
}
.user-avatar {
flex-basis: 3rem;
flex-shrink: 0;
position: relative;
img {
width: 100%;
}
&.is-iocaine {
img {
filter: hue-rotate(150deg) saturate(200%);
}
}
.iocaine-symbol {
left: -.5rem;
position: absolute;
top: -.75rem;
z-index: 9;
svg {
background: $grayer;
border-radius: .25rem;
fill: $white;
min-height: 1.75rem;
min-width: 1.75rem;
padding: .25rem;
}
}
}
}