mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-16 18:14:30 +08:00
Update Invite new user to team modal [SCI-5097]
This commit is contained in:
parent
fb105f8632
commit
ecec1ce194
8 changed files with 109 additions and 33 deletions
|
@ -8,6 +8,7 @@
|
|||
data-select-by-group // Add groups to dropdown
|
||||
data-disable-placeholder // Placeholder for disabled fields
|
||||
data-placeholder // Search placeholder
|
||||
data-select-hint // A hint on top of a dropdown
|
||||
data-disable-on-load // Disable input after initialization
|
||||
data-select-all-button // Text for select all button
|
||||
data-combine-tags // Combine multiple tags to one (in simple mode gives you multiple select)
|
||||
|
@ -173,6 +174,10 @@ var dropdownSelector = (function() {
|
|||
};
|
||||
}
|
||||
|
||||
function noOptionsForSelect(selector) {
|
||||
return !$(selector).data('ajax-url') && $(selector).find('.dropdown-option').length == 0;
|
||||
}
|
||||
|
||||
// Ajax intial values, we will use default options //
|
||||
function ajaxInitialValues(selector, container) {
|
||||
var intialData = [];
|
||||
|
@ -200,13 +205,13 @@ var dropdownSelector = (function() {
|
|||
}
|
||||
|
||||
// Prepare custom dropdown icon
|
||||
function prepareCustomDropdownIcon(config) {
|
||||
function prepareCustomDropdownIcon(selector, config) {
|
||||
if (config.inputTagMode && noOptionsForSelect(selector)) {
|
||||
return '';
|
||||
}
|
||||
if (config.customDropdownIcon) {
|
||||
return config.customDropdownIcon();
|
||||
}
|
||||
if (config.inputTagMode) {
|
||||
return '';
|
||||
}
|
||||
return '<i class="fas fa-caret-down right-icon"></i><i class="fas fa-search right-icon"></i>';
|
||||
}
|
||||
|
||||
|
@ -305,7 +310,7 @@ var dropdownSelector = (function() {
|
|||
<div class="dropdown-container"></div>
|
||||
<div class="input-field">
|
||||
<input type="text" class="search-field" data-options-selected=0 placeholder="${selectElement.data('placeholder') || ''}"></input>
|
||||
${prepareCustomDropdownIcon(config)}
|
||||
${prepareCustomDropdownIcon(selector, config)}
|
||||
</div>
|
||||
<input type="hidden" class="data-field" value="[]">
|
||||
|
||||
|
@ -378,8 +383,8 @@ var dropdownSelector = (function() {
|
|||
dropdownContainer.addClass('active');
|
||||
$('.dropdown-selector-container:not(.active)').removeClass('open');
|
||||
|
||||
// If dropdown disabled or we use it in tag mode we not open it
|
||||
if (dropdownContainer.hasClass('disabled') || config.inputTagMode) return;
|
||||
// If dropdown disabled or we use it in only tag mode we not open it
|
||||
if (dropdownContainer.hasClass('disabled') || (config.inputTagMode && noOptionsForSelect(selector))) return;
|
||||
|
||||
// Each time we open option contianer we must scroll it
|
||||
optionContainer.scrollTo(0);
|
||||
|
@ -521,10 +526,15 @@ var dropdownSelector = (function() {
|
|||
}
|
||||
|
||||
// Remove placeholder from option container
|
||||
container.find('.dropdown-group, .dropdown-option, .empty-dropdown, .delimiter').remove();
|
||||
container.find('.dropdown-group, .dropdown-option, .empty-dropdown, .dropdown-hint, .delimiter').remove();
|
||||
if (!data) return;
|
||||
|
||||
if (data.length > 0 && !(data.length === 1 && data[0].value === '')) {
|
||||
if (selector.data('select-hint')) {
|
||||
$(`<div class="dropdown-hint">${selector.data('select-hint')}</div>`)
|
||||
.appendTo(container.find('.dropdown-container'));
|
||||
}
|
||||
|
||||
// If we use select-by-group option we need first draw groups
|
||||
if (selector.data('select-by-group')) {
|
||||
$.each(data, function(gi, group) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* globals dropdownSelector animateSpinner */
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
|
@ -23,13 +25,38 @@
|
|||
var teamSelectorCheckbox = modal.find('[data-role=team-selector-checkbox]');
|
||||
var teamSelectorDropdown = modal.find('[data-role=team-selector-dropdown]');
|
||||
var teamSelectorDropdown2 = $();
|
||||
var tagsInput = modal.find('[data-role=tags-input]');
|
||||
var emailsInput = modal.find('.emails-input');
|
||||
var recaptchaErrorMsgDiv = modal.find('#recaptcha-error-msg');
|
||||
var recaptchaErrorText = modal.find('#recaptcha-error-msg>span');
|
||||
|
||||
// Set max tags
|
||||
tagsInput.tagsinput({
|
||||
maxTags: modal.data('max-tags')
|
||||
dropdownSelector.init(emailsInput, {
|
||||
delimiter: true,
|
||||
optionClass: 'users-dropdown-list',
|
||||
optionLabel: (data) => {
|
||||
return `<img class="item-avatar" src="${data.params.avatar_url}"/>
|
||||
${data.label}
|
||||
<span class="item-email pull-right">${data.params.email}</span>`;
|
||||
},
|
||||
tagLabel: (data) => {
|
||||
if (data.params) {
|
||||
return `<img class="item-avatar" src="${data.params.avatar_url}"/> ${data.label}`;
|
||||
}
|
||||
return data.label;
|
||||
},
|
||||
labelHTML: true,
|
||||
tagClass: 'users-dropdown-list',
|
||||
inputTagMode: true,
|
||||
customDropdownIcon: () => { return '<i class="fas fa-search pull-right"></i>'; },
|
||||
onChange: () => {
|
||||
let values = dropdownSelector.getValues(emailsInput);
|
||||
if (values.length > 0) {
|
||||
inviteBtn.removeAttr('disabled');
|
||||
inviteWithRoleBtn.removeAttr('disabled');
|
||||
} else {
|
||||
inviteBtn.attr('disabled', 'disabled');
|
||||
inviteWithRoleBtn.attr('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modal.off('show.bs.modal').on('show.bs.modal', function() {
|
||||
|
@ -83,21 +110,10 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Toggle depending on input tags
|
||||
tagsInput.on('itemAdded', function() {
|
||||
inviteBtn.removeAttr('disabled');
|
||||
inviteWithRoleBtn.removeAttr('disabled');
|
||||
}).on('itemRemoved', function() {
|
||||
if ($(this).val() === null) {
|
||||
inviteBtn.attr('disabled', 'disabled');
|
||||
inviteWithRoleBtn.attr('disabled', 'disabled');
|
||||
}
|
||||
});
|
||||
|
||||
// Click action
|
||||
modal.find('[data-action=invite]').off('click').on('click', function() {
|
||||
var data = {
|
||||
emails: tagsInput.val(),
|
||||
emails: dropdownSelector.getValues(emailsInput),
|
||||
'g-recaptcha-response': $('#recaptcha-invite-modal').val()
|
||||
};
|
||||
|
||||
|
@ -159,7 +175,7 @@
|
|||
});
|
||||
}).on('shown.bs.modal', function() {
|
||||
var script = document.createElement('script');
|
||||
tagsInput.tagsinput('focus');
|
||||
emailsInput.focus();
|
||||
recaptchaErrorMsgDiv.addClass('hidden');
|
||||
script.type = 'text/javascript';
|
||||
script.src = 'https://www.google.com/recaptcha/api.js?hl=en';
|
||||
|
@ -168,7 +184,7 @@
|
|||
modal.removeAttr('data-invited');
|
||||
}).on('hide.bs.modal', function() {
|
||||
// 'Reset' modal state
|
||||
tagsInput.tagsinput('removeAll');
|
||||
dropdownSelector.clearData(emailsInput);
|
||||
teamSelectorCheckbox.prop('checked', false);
|
||||
inviteBtn.attr('disabled', 'disabled');
|
||||
inviteWithRoleBtn.attr('disabled', 'disabled');
|
||||
|
@ -179,7 +195,6 @@
|
|||
|
||||
// Unbind event listeners
|
||||
teamSelectorCheckbox.off('change');
|
||||
tagsInput.off('itemAdded itemRemoved');
|
||||
modal.find('[data-action=invite]').off('click');
|
||||
|
||||
// Hide contents of the results <div>
|
||||
|
|
|
@ -165,4 +165,44 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-invite-users {
|
||||
.user-selector {
|
||||
.fa-search {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.open {
|
||||
.input-field {
|
||||
border: 1px solid $brand-focus;
|
||||
border-radius: $border-radius-small;
|
||||
|
||||
.fa-search {
|
||||
color: $brand-focus;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-field {
|
||||
padding: 3px 6px 3px 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.users-dropdown-list {
|
||||
border-top: 1px solid $color-gainsboro;
|
||||
|
||||
.item-avatar {
|
||||
border-radius: 50%;
|
||||
height: 20px;
|
||||
margin: 0 .5em 0 0;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.item-email {
|
||||
color: $color-silver-chalice;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,6 +135,12 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.dropdown-hint {
|
||||
opacity: .6;
|
||||
padding: 7px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.delimiter {
|
||||
background: $color-alto;
|
||||
height: 1px;
|
||||
|
|
|
@ -71,10 +71,12 @@ invite_to_team = type.in?(%w(invite_to_team invite_to_team_with_role))
|
|||
<% end %>
|
||||
</p>
|
||||
|
||||
<select class="emails-input" multiple data-role="tags-input" name="emails[]">
|
||||
</select>
|
||||
<br />
|
||||
<em><%= t('invite_users.input_subtitle') %></em>
|
||||
<div class="user-selector">
|
||||
<select class="emails-input" multiple data-role="tags-input" name="emails[]">
|
||||
</select>
|
||||
<br />
|
||||
<label><%= t('invite_users.input_subtitle') %></label>
|
||||
</div>
|
||||
|
||||
<% if current_user && type.in?(['invite_with_team_selector', 'invite_with_team_selector_and_role']) %>
|
||||
<% # Only allow inviting to teams where user is admin %>
|
||||
|
|
|
@ -8,6 +8,8 @@ Devise.setup do |config|
|
|||
# by default. You can change it below and use your own secret key.
|
||||
# config.secret_key = '8d3a7b1acfb05057553abeb1ee4709f9f2d7e2fa1e5e60e7f45ab2e9244c301adcf0d146ae7cf74ba03c39c5bf895f08606a9f98051478ac4c6a695cafb4007a'
|
||||
|
||||
Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION.concat(%i(otp otp_recovery_codes otp_secret))
|
||||
|
||||
# ==> Mailer Configuration
|
||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
# note that it will be overwritten if you use your own mailer class
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
Rails.application.config.filter_parameters += [
|
||||
:password, :image, /^avatar$/, :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
||||
:password, :image, /^avatar$/, :passw, :secret, :token, :_key, :crypt, :salt,
|
||||
:certificate, :otp, :otp_recovery_codes, :otp_secret, :ssn
|
||||
]
|
||||
|
|
|
@ -2209,7 +2209,7 @@ en:
|
|||
heading: "Invite more people to start using SciNote."
|
||||
input_subtitle: "Input one or multiple emails, confirm each email with ENTER key."
|
||||
invite_to_team_heading: "Invite users to my team:"
|
||||
invite_btn: "Invite Users"
|
||||
invite_btn: "Invite members"
|
||||
invite_guest: "As Guests"
|
||||
invite_user: "As Normal Users"
|
||||
invite_admin: "As Administrators"
|
||||
|
|
Loading…
Add table
Reference in a new issue