mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 15:30:13 +01:00
Allow a user to edit its profile or avatar from a member popover
Fixes the data context on the member popover in the details pane. Also change the way Popover detect if the click is initiated from a parent popover -- from reading Blaze context, to looking at the event target parents.
This commit is contained in:
parent
fad4cba5e2
commit
8cf9ec2660
8 changed files with 70 additions and 55 deletions
|
|
@ -44,8 +44,9 @@ template(name="boardMenuPopup")
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
li: a.js-open-archives Archived elements
|
li: a.js-open-archives Archived elements
|
||||||
li: a.js-change-board-color Change color
|
if currentUser.isBoardAdmin
|
||||||
li: a Permissions
|
li: a.js-change-board-color Change color
|
||||||
|
li: a Permissions
|
||||||
hr
|
hr
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
li: a Copy this board
|
li: a Copy this board
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ template(name="cardDetails")
|
||||||
a.card-label.add-label.js-add-labels
|
a.card-label.add-label.js-add-labels
|
||||||
i.fa.fa-plus
|
i.fa.fa-plus
|
||||||
|
|
||||||
//- XXX We should use "editable" to avoide repetiting ourselves
|
//- XXX We should use "editable" to avoid repetiting ourselves
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
h3.card-details-item-title Description
|
h3.card-details-item-title Description
|
||||||
+inlinedForm(classNames="card-description js-card-description")
|
+inlinedForm(classNames="card-description js-card-description")
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,6 @@ template(name="cardLabelsPopup")
|
||||||
span.card-label.card-label-selectable.js-select-label(class="card-label-{{color}}"
|
span.card-label.card-label-selectable.js-select-label(class="card-label-{{color}}"
|
||||||
class="{{# if isLabelSelected ../_id }}active{{/ if }}")
|
class="{{# if isLabelSelected ../_id }}active{{/ if }}")
|
||||||
= name
|
= name
|
||||||
if currentUser.isBoardAdmin
|
if isLabelSelected ../_id
|
||||||
span.card-label-selectable-icon.fa.fa-check
|
i.card-label-selectable-icon.fa.fa-check
|
||||||
a.quiet-button.full.js-add-label {{_ 'label-create'}}
|
a.quiet-button.full.js-add-label {{_ 'label-create'}}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,11 @@ template(name="userAvatar")
|
||||||
span.member-presence-status(class=presenceStatusClassName)
|
span.member-presence-status(class=presenceStatusClassName)
|
||||||
span.member-type(class=memberType)
|
span.member-type(class=memberType)
|
||||||
|
|
||||||
|
if showEdit
|
||||||
|
if $eq currentUser._id userData._id
|
||||||
|
a.edit-avatar.js-change-avatar
|
||||||
|
i.fa.fa-pencil
|
||||||
|
|
||||||
template(name="userAvatarInitials")
|
template(name="userAvatarInitials")
|
||||||
svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15")
|
svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15")
|
||||||
text(x="0" y="13")= initials
|
text(x="0" y="13")= initials
|
||||||
|
|
@ -18,9 +23,8 @@ template(name="userPopup")
|
||||||
.mini-profile-info
|
.mini-profile-info
|
||||||
+userAvatar(userId=user._id)
|
+userAvatar(userId=user._id)
|
||||||
.info
|
.info
|
||||||
h3.bottom
|
h3= user.profile.fullname
|
||||||
= user.profile.fullname
|
p.quiet @{{ user.username }}
|
||||||
p.quiet.bottom @{{ user.username }}
|
|
||||||
|
|
||||||
template(name="memberName")
|
template(name="memberName")
|
||||||
if showBoth
|
if showBoth
|
||||||
|
|
@ -61,10 +65,14 @@ template(name="changeAvatarPopup")
|
||||||
template(name="cardMemberPopup")
|
template(name="cardMemberPopup")
|
||||||
.board-member-menu
|
.board-member-menu
|
||||||
.mini-profile-info
|
.mini-profile-info
|
||||||
+userAvatar(userId=user._id)
|
+userAvatar(userId=user._id showEdit=true)
|
||||||
.info
|
.info
|
||||||
h3.bottom= user.profile.fullname
|
h3= user.profile.fullname
|
||||||
p.quiet.bottom @{{ user.username }}
|
p.quiet @{{ user.username }}
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
li: a.js-remove-member {{_ 'remove-member-from-card'}}
|
li: a.js-remove-member {{_ 'remove-member-from-card'}}
|
||||||
|
|
||||||
|
if $eq currentUser._id user._id
|
||||||
|
with currentUser
|
||||||
|
li: a.js-edit-profile Edit Profile
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ Template.userAvatar.helpers({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.userAvatar.events({
|
||||||
|
'click .js-change-avatar': Popup.open('changeAvatar')
|
||||||
|
});
|
||||||
|
|
||||||
Template.userAvatarInitials.helpers({
|
Template.userAvatarInitials.helpers({
|
||||||
initials: function() {
|
initials: function() {
|
||||||
var user = Users.findOne(this.userId);
|
var user = Users.findOne(this.userId);
|
||||||
|
|
@ -142,9 +146,16 @@ Template.cardMembersPopup.events({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.cardMemberPopup.helpers({
|
||||||
|
user: function() {
|
||||||
|
return Users.findOne(this.userId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Template.cardMemberPopup.events({
|
Template.cardMemberPopup.events({
|
||||||
'click .js-remove-member': function() {
|
'click .js-remove-member': function() {
|
||||||
Cards.update(this.cardId, {$pull: {members: this.userId}});
|
Cards.update(this.cardId, {$pull: {members: this.userId}});
|
||||||
Popup.close();
|
Popup.close();
|
||||||
}
|
},
|
||||||
|
'click .js-edit-profile': Popup.open('editProfile')
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -56,39 +56,24 @@ avatar-radius = 50%
|
||||||
background: #bdbdbd
|
background: #bdbdbd
|
||||||
border-color: #ededed
|
border-color: #ededed
|
||||||
|
|
||||||
&.extra-small
|
.edit-avatar
|
||||||
.avatar-initials
|
position: absolute
|
||||||
font-size: 9px
|
top: 0
|
||||||
width: 18px
|
height: 100%
|
||||||
height: 18px
|
width: 100%
|
||||||
line-height: 18px
|
border-radius: avatar-radius
|
||||||
|
background: black
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
.avatar-image
|
&:hover
|
||||||
width: 18px
|
opacity: 0.6
|
||||||
height: 18px
|
|
||||||
|
|
||||||
&.small
|
i.fa-pencil
|
||||||
width: 30px
|
color: white
|
||||||
height: 30px
|
|
||||||
|
|
||||||
.avatar-initials
|
|
||||||
font-size: 12px
|
|
||||||
line-height: 30px
|
|
||||||
|
|
||||||
&.large
|
|
||||||
height: 85px
|
|
||||||
line-height: 85px
|
|
||||||
width: 85px
|
|
||||||
|
|
||||||
.avatar
|
|
||||||
width: 85px
|
|
||||||
height: 85px
|
|
||||||
|
|
||||||
.avatar-initials
|
|
||||||
font-size: 16px
|
|
||||||
font-weight: 700
|
|
||||||
line-height: 85px
|
|
||||||
width: 85px
|
|
||||||
|
|
||||||
&.add-member
|
&.add-member
|
||||||
display: flex
|
display: flex
|
||||||
|
|
@ -106,3 +91,19 @@ avatar-radius = 50%
|
||||||
&.me
|
&.me
|
||||||
background: #cfdfe8
|
background: #cfdfe8
|
||||||
|
|
||||||
|
.mini-profile-info
|
||||||
|
margin-top: 10px
|
||||||
|
|
||||||
|
.info
|
||||||
|
padding-top: 5px
|
||||||
|
|
||||||
|
h3, p
|
||||||
|
margin-bottom: 0
|
||||||
|
|
||||||
|
p
|
||||||
|
padding-top: 0
|
||||||
|
|
||||||
|
.member
|
||||||
|
width: 50px
|
||||||
|
height: @width
|
||||||
|
margin-right: 10px
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ template(name="editProfilePopup")
|
||||||
form
|
form
|
||||||
label
|
label
|
||||||
| {{_ "fullname"}}
|
| {{_ "fullname"}}
|
||||||
input.js-profile-fullname(type="text" value=profile.name autofocus)
|
input.js-profile-fullname(type="text" value=profile.fullname autofocus)
|
||||||
label
|
label
|
||||||
| {{_ "username"}}
|
| {{_ "username"}}
|
||||||
input.js-profile-username(type="text" value=username)
|
input.js-profile-username(type="text" value=username)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@ Popup = {
|
||||||
var self = this;
|
var self = this;
|
||||||
var popupName = name + 'Popup';
|
var popupName = name + 'Popup';
|
||||||
|
|
||||||
|
var clickFromPopup = function(evt) {
|
||||||
|
return $(evt.target).closest('.js-pop-over').length !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
return function(evt) {
|
return function(evt) {
|
||||||
// If a popup is already openened, clicking again on the opener element
|
// If a popup is already openened, clicking again on the opener element
|
||||||
// should close it -- and interupt the current `open` function.
|
// should close it -- and interupt the current `open` function.
|
||||||
|
|
@ -34,7 +38,7 @@ Popup = {
|
||||||
// has one. This allows us to position a sub-popup exactly at the same
|
// has one. This allows us to position a sub-popup exactly at the same
|
||||||
// position than its parent.
|
// position than its parent.
|
||||||
var openerElement;
|
var openerElement;
|
||||||
if (self._hasPopupParent()) {
|
if (clickFromPopup(evt)) {
|
||||||
openerElement = self._getTopStack().openerElement;
|
openerElement = self._getTopStack().openerElement;
|
||||||
} else {
|
} else {
|
||||||
self._stack = [];
|
self._stack = [];
|
||||||
|
|
@ -47,9 +51,8 @@ Popup = {
|
||||||
// We push our popup data to the stack. The top of the stack is always
|
// We push our popup data to the stack. The top of the stack is always
|
||||||
// used as the data source for our current popup.
|
// used as the data source for our current popup.
|
||||||
self._stack.push({
|
self._stack.push({
|
||||||
__isPopup: true,
|
|
||||||
popupName: popupName,
|
popupName: popupName,
|
||||||
hasPopupParent: self._hasPopupParent(),
|
hasPopupParent: clickFromPopup(evt),
|
||||||
title: self._getTitle(popupName),
|
title: self._getTitle(popupName),
|
||||||
openerElement: openerElement,
|
openerElement: openerElement,
|
||||||
depth: self._stack.length,
|
depth: self._stack.length,
|
||||||
|
|
@ -155,15 +158,6 @@ Popup = {
|
||||||
return this._stack[this._stack.length - 1];
|
return this._stack[this._stack.length - 1];
|
||||||
},
|
},
|
||||||
|
|
||||||
// We use the blaze API to determine if the current popup has been opened from
|
|
||||||
// a parent popup. The number we give to the `Template.parentData` has been
|
|
||||||
// determined experimentally and is susceptible to change if you modify the
|
|
||||||
// `Popup.template`
|
|
||||||
_hasPopupParent: function() {
|
|
||||||
var tryParentData = Template.parentData(3);
|
|
||||||
return !! (tryParentData && tryParentData.__isPopup);
|
|
||||||
},
|
|
||||||
|
|
||||||
// We automatically calculate the popup offset from the reference element
|
// We automatically calculate the popup offset from the reference element
|
||||||
// position and dimensions. We also reactively use the window dimensions to
|
// position and dimensions. We also reactively use the window dimensions to
|
||||||
// ensure that the popup is always visible on the screen.
|
// ensure that the popup is always visible on the screen.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue