mirror of
https://github.com/wekan/wekan.git
synced 2025-12-17 07:50:12 +01:00
parent
bd1837ee36
commit
c6d4600683
5 changed files with 173 additions and 23 deletions
|
|
@ -56,17 +56,17 @@ template(name="importMapMembersAddPopup")
|
||||||
p
|
p
|
||||||
| {{_ 'import-user-select'}}
|
| {{_ 'import-user-select'}}
|
||||||
.js-map-member
|
.js-map-member
|
||||||
+EasySearch.Input(index=searchIndex)
|
input.js-search-member-input(type="text" placeholder="{{_ 'search-users'}}")
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
+EasySearch.Each(index=searchIndex)
|
each searchResults
|
||||||
li.item.js-member-item
|
li.item.js-member-item
|
||||||
a.name.js-select-import(title="{{profile.fullname}} ({{username}})" data-id="{{__originalId}}")
|
a.name.js-select-import(title="{{profile.fullname}} ({{username}})" data-id="{{_id}}")
|
||||||
+userAvatar(userId=__originalId)
|
+userAvatar(userId=_id)
|
||||||
span.full-name
|
span.full-name
|
||||||
= profile.fullname
|
= profile.fullname
|
||||||
| (<span class="username">{{username}}</span>)
|
| (<span class="username">{{username}}</span>)
|
||||||
+EasySearch.IfSearching(index=searchIndex)
|
if searching.get
|
||||||
+spinner
|
+spinner
|
||||||
+EasySearch.IfNoResults(index=searchIndex)
|
if noResults.get
|
||||||
.manage-member-section
|
.manage-member-section
|
||||||
p.quiet {{_ 'no-results'}}
|
p.quiet {{_ 'no-results'}}
|
||||||
|
|
|
||||||
|
|
@ -311,6 +311,73 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
}).register('importMapMembersAddPopup');
|
}).register('importMapMembersAddPopup');
|
||||||
|
|
||||||
|
// Global reactive variables for import member popup
|
||||||
|
const importMemberPopupState = {
|
||||||
|
searching: new ReactiveVar(false),
|
||||||
|
searchResults: new ReactiveVar([]),
|
||||||
|
noResults: new ReactiveVar(false),
|
||||||
|
searchTimeout: null
|
||||||
|
};
|
||||||
|
|
||||||
|
BlazeComponent.extendComponent({
|
||||||
|
onCreated() {
|
||||||
|
// Use global state
|
||||||
|
this.searching = importMemberPopupState.searching;
|
||||||
|
this.searchResults = importMemberPopupState.searchResults;
|
||||||
|
this.noResults = importMemberPopupState.noResults;
|
||||||
|
this.searchTimeout = importMemberPopupState.searchTimeout;
|
||||||
|
},
|
||||||
|
|
||||||
|
onRendered() {
|
||||||
|
this.find('.js-search-member-input').focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
performSearch(query) {
|
||||||
|
if (!query || query.length < 2) {
|
||||||
|
this.searchResults.set([]);
|
||||||
|
this.noResults.set(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.searching.set(true);
|
||||||
|
this.noResults.set(false);
|
||||||
|
|
||||||
|
const results = UserSearchIndex.search(query, { limit: 20 }).fetch();
|
||||||
|
this.searchResults.set(results);
|
||||||
|
this.searching.set(false);
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
this.noResults.set(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'keyup .js-search-member-input'(event) {
|
||||||
|
const query = event.target.value.trim();
|
||||||
|
|
||||||
|
if (this.searchTimeout) {
|
||||||
|
clearTimeout(this.searchTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.searchTimeout = setTimeout(() => {
|
||||||
|
this.performSearch(query);
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
}).register('importMapMembersAddPopupSearch');
|
||||||
|
|
||||||
Template.importMapMembersAddPopup.helpers({
|
Template.importMapMembersAddPopup.helpers({
|
||||||
searchIndex: () => UserSearchIndex,
|
searchResults() {
|
||||||
|
return importMemberPopupState.searchResults.get();
|
||||||
|
},
|
||||||
|
searching() {
|
||||||
|
return importMemberPopupState.searching;
|
||||||
|
},
|
||||||
|
noResults() {
|
||||||
|
return importMemberPopupState.noResults;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -631,7 +631,7 @@ template(name="removeBoardTeamPopup")
|
||||||
|
|
||||||
template(name="addMemberPopup")
|
template(name="addMemberPopup")
|
||||||
.js-search-member
|
.js-search-member
|
||||||
+EasySearch.Input(index=searchIndex)
|
input.js-search-member-input(type="text" placeholder="{{_ 'email-address'}}")
|
||||||
|
|
||||||
if loading.get
|
if loading.get
|
||||||
+spinner
|
+spinner
|
||||||
|
|
@ -639,25 +639,38 @@ template(name="addMemberPopup")
|
||||||
.warning {{_ error.get}}
|
.warning {{_ error.get}}
|
||||||
else
|
else
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
+EasySearch.Each(index=searchIndex)
|
each searchResults
|
||||||
li.item.js-member-item(class="{{#if isBoardMember}}disabled{{/if}}")
|
li.item.js-member-item(class="{{#if isBoardMember}}disabled{{/if}}")
|
||||||
a.name.js-select-member(title="{{profile.fullname}} ({{username}})")
|
a.name.js-select-member(title="{{profile.fullname}} ({{username}})")
|
||||||
+userAvatar(userId=__originalId)
|
+userAvatar(userId=_id)
|
||||||
span.full-name
|
span.full-name
|
||||||
= profile.fullname
|
= profile.fullname
|
||||||
| (<span class="username">{{username}}</span>)
|
| (<span class="username">{{username}}</span>)
|
||||||
if isBoardMember
|
if isBoardMember
|
||||||
.quiet ({{_ 'joined'}})
|
.quiet ({{_ 'joined'}})
|
||||||
|
|
||||||
+EasySearch.IfSearching(index=searchIndex)
|
if searching.get
|
||||||
+spinner
|
+spinner
|
||||||
|
|
||||||
+EasySearch.IfNoResults(index=searchIndex)
|
if noResults.get
|
||||||
.manage-member-section
|
.manage-member-section
|
||||||
p.quiet {{_ 'no-results'}}
|
p.quiet {{_ 'no-results'}}
|
||||||
button.js-email-invite.primary.full {{_ 'email-invite'}}
|
button.js-email-invite.primary.full {{_ 'email-invite'}}
|
||||||
|
|
||||||
|
|
||||||
|
template(name="addMemberPopupTest")
|
||||||
|
.js-search-member
|
||||||
|
input.js-search-member-input(type="text" placeholder="{{_ 'email-address'}}")
|
||||||
|
ul.pop-over-list
|
||||||
|
each searchResults
|
||||||
|
li.item.js-member-item
|
||||||
|
a.name.js-select-member(title="{{profile.fullname}} ({{username}})")
|
||||||
|
+userAvatar(userId=_id)
|
||||||
|
span.full-name
|
||||||
|
= profile.fullname
|
||||||
|
| (<span class="username">{{username}}</span>)
|
||||||
|
button.js-email-invite.primary.full {{_ 'email-invite'}}
|
||||||
|
|
||||||
template(name="changePermissionsPopup")
|
template(name="changePermissionsPopup")
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
li
|
li
|
||||||
|
|
|
||||||
|
|
@ -1492,19 +1492,28 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
}).register('boardCardSettingsPopup');
|
}).register('boardCardSettingsPopup');
|
||||||
|
|
||||||
|
// Use Session variables instead of global ReactiveVars
|
||||||
|
Session.setDefault('addMemberPopup.searchResults', []);
|
||||||
|
Session.setDefault('addMemberPopup.searching', false);
|
||||||
|
Session.setDefault('addMemberPopup.noResults', false);
|
||||||
|
Session.setDefault('addMemberPopup.loading', false);
|
||||||
|
Session.setDefault('addMemberPopup.error', '');
|
||||||
|
|
||||||
|
console.log('addMemberPopup Session variables initialized');
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
onCreated() {
|
onCreated() {
|
||||||
this.error = new ReactiveVar('');
|
// Use Session variables
|
||||||
this.loading = new ReactiveVar(false);
|
this.searchTimeout = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
onRendered() {
|
onRendered() {
|
||||||
this.find('.js-search-member input').focus();
|
this.find('.js-search-member-input').focus();
|
||||||
this.setLoading(false);
|
this.setLoading(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
isBoardMember() {
|
isBoardMember() {
|
||||||
const userId = this.currentData().__originalId;
|
const userId = this.currentData()._id;
|
||||||
const user = ReactiveCache.getUser(userId);
|
const user = ReactiveCache.getUser(userId);
|
||||||
return user && user.isBoardMember();
|
return user && user.isBoardMember();
|
||||||
},
|
},
|
||||||
|
|
@ -1514,15 +1523,35 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
setError(error) {
|
setError(error) {
|
||||||
this.error.set(error);
|
Session.set('addMemberPopup.error', error);
|
||||||
},
|
},
|
||||||
|
|
||||||
setLoading(w) {
|
setLoading(w) {
|
||||||
this.loading.set(w);
|
Session.set('addMemberPopup.loading', w);
|
||||||
},
|
},
|
||||||
|
|
||||||
isLoading() {
|
isLoading() {
|
||||||
return this.loading.get();
|
return Session.get('addMemberPopup.loading');
|
||||||
|
},
|
||||||
|
|
||||||
|
performSearch(query) {
|
||||||
|
if (!query || query.length < 2) {
|
||||||
|
Session.set('addMemberPopup.searchResults', []);
|
||||||
|
Session.set('addMemberPopup.noResults', false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Session.set('addMemberPopup.searching', true);
|
||||||
|
Session.set('addMemberPopup.noResults', false);
|
||||||
|
|
||||||
|
// Use the fallback search
|
||||||
|
const results = UserSearchIndex.search(query, { limit: 20 }).fetch();
|
||||||
|
Session.set('addMemberPopup.searchResults', results);
|
||||||
|
Session.set('addMemberPopup.searching', false);
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
Session.set('addMemberPopup.noResults', true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
inviteUser(idNameEmail) {
|
inviteUser(idNameEmail) {
|
||||||
|
|
@ -1540,18 +1569,30 @@ BlazeComponent.extendComponent({
|
||||||
events() {
|
events() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'keyup input'() {
|
'keyup .js-search-member-input'(event) {
|
||||||
this.setError('');
|
this.setError('');
|
||||||
|
const query = event.target.value.trim();
|
||||||
|
this.searchQuery.set(query);
|
||||||
|
|
||||||
|
// Clear previous timeout
|
||||||
|
if (this.searchTimeout) {
|
||||||
|
clearTimeout(this.searchTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debounce search
|
||||||
|
this.searchTimeout = setTimeout(() => {
|
||||||
|
this.performSearch(query);
|
||||||
|
}, 300);
|
||||||
},
|
},
|
||||||
'click .js-select-member'() {
|
'click .js-select-member'() {
|
||||||
const userId = this.currentData().__originalId;
|
const userId = this.currentData()._id;
|
||||||
const currentBoard = Utils.getCurrentBoard();
|
const currentBoard = Utils.getCurrentBoard();
|
||||||
if (!currentBoard.hasMember(userId)) {
|
if (!currentBoard.hasMember(userId)) {
|
||||||
this.inviteUser(userId);
|
this.inviteUser(userId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'click .js-email-invite'() {
|
'click .js-email-invite'() {
|
||||||
const idNameEmail = $('.js-search-member input').val();
|
const idNameEmail = $('.js-search-member-input').val();
|
||||||
if (idNameEmail.indexOf('@') < 0 || this.isValidEmail(idNameEmail)) {
|
if (idNameEmail.indexOf('@') < 0 || this.isValidEmail(idNameEmail)) {
|
||||||
this.inviteUser(idNameEmail);
|
this.inviteUser(idNameEmail);
|
||||||
} else this.setError('email-invalid');
|
} else this.setError('email-invalid');
|
||||||
|
|
@ -1562,7 +1603,35 @@ BlazeComponent.extendComponent({
|
||||||
}).register('addMemberPopup');
|
}).register('addMemberPopup');
|
||||||
|
|
||||||
Template.addMemberPopup.helpers({
|
Template.addMemberPopup.helpers({
|
||||||
searchIndex: () => UserSearchIndex,
|
searchResults() {
|
||||||
|
const results = Session.get('addMemberPopup.searchResults');
|
||||||
|
console.log('searchResults helper called, returning:', results);
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
searching() {
|
||||||
|
return Session.get('addMemberPopup.searching');
|
||||||
|
},
|
||||||
|
noResults() {
|
||||||
|
return Session.get('addMemberPopup.noResults');
|
||||||
|
},
|
||||||
|
loading() {
|
||||||
|
return Session.get('addMemberPopup.loading');
|
||||||
|
},
|
||||||
|
error() {
|
||||||
|
return Session.get('addMemberPopup.error');
|
||||||
|
},
|
||||||
|
isBoardMember() {
|
||||||
|
const userId = this._id;
|
||||||
|
const user = ReactiveCache.getUser(userId);
|
||||||
|
return user && user.isBoardMember();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Template.addMemberPopupTest.helpers({
|
||||||
|
searchResults() {
|
||||||
|
console.log('addMemberPopupTest searchResults helper called');
|
||||||
|
return Session.get('addMemberPopup.searchResults') || [];
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
|
|
|
||||||
|
|
@ -385,6 +385,7 @@
|
||||||
"editNotificationPopup-title": "Edit Notification",
|
"editNotificationPopup-title": "Edit Notification",
|
||||||
"editProfilePopup-title": "Edit Profile",
|
"editProfilePopup-title": "Edit Profile",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
|
"email-address": "Email Address",
|
||||||
"email-enrollAccount-subject": "An account created for you on __siteName__",
|
"email-enrollAccount-subject": "An account created for you on __siteName__",
|
||||||
"email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.",
|
"email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.",
|
||||||
"email-fail": "Sending email failed",
|
"email-fail": "Sending email failed",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue