mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Add select/remove all options for emails
This commit is contained in:
parent
e9725a0081
commit
2b22f8eb4f
4 changed files with 100 additions and 24 deletions
|
@ -131,19 +131,19 @@ select.form-control:focus,
|
|||
.react-selectize.root-node.open .react-selectize-control .react-selectize-toggle-button path {
|
||||
fill: #999 !important;
|
||||
}
|
||||
.selectize-control .selectize-input > div .email {
|
||||
.selectize-control .selectize-input > div .item-value {
|
||||
opacity: 0.8;
|
||||
font-size: 12px;
|
||||
}
|
||||
.selectize-control .selectize-input > div .user + .email {
|
||||
.selectize-control .selectize-input > div .item-text + .item-value {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.selectize-control .selectize-input > div .email:before {
|
||||
.selectize-control .selectize-input > div .item-value:before {
|
||||
content: '<';
|
||||
opacity: 0.8;
|
||||
font-size: 12px;
|
||||
}
|
||||
.selectize-control .selectize-input > div .email:after {
|
||||
.selectize-control .selectize-input > div .item-value:after {
|
||||
content: '>';
|
||||
opacity: 0.8;
|
||||
font-size: 12px;
|
||||
|
@ -153,6 +153,25 @@ select.form-control:focus,
|
|||
display: block;
|
||||
color: #a0a0a0;
|
||||
}
|
||||
.selectize-control .selectize-dropdown .select-all,
|
||||
.selectize-control .selectize-dropdown .remove-all {
|
||||
font-weight: bold;
|
||||
}
|
||||
.selectize-control .selectize-dropdown .border-all {
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
height: 1px;
|
||||
margin: 9px -12px 9px -12px;
|
||||
padding: 0 !important;
|
||||
overflow: hidden;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
.selectize-control .selectize-dropdown .border-all:last-child {
|
||||
display: none;
|
||||
}
|
||||
.selectize-dropdown .optgroup-header {
|
||||
font-weight: bold;
|
||||
}
|
||||
select.form-control option {
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
|
|
|
@ -98,6 +98,33 @@
|
|||
</div>
|
||||
<p class="help-block">${item['description'] | n}</p>
|
||||
</div>
|
||||
% elif item['input_type'] == 'selectize':
|
||||
<div class="form-group">
|
||||
<label for="${item['name']}">${item['label']}</label>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<select class="form-control" id="${item['name']}" name="${item['name']}">
|
||||
<option value="select-all">Select All</option>
|
||||
<option value="remove-all">Remove All</option>
|
||||
% if isinstance(item['select_options'], dict):
|
||||
% for section, options in item['select_options'].iteritems():
|
||||
<optgroup label="${section}">
|
||||
% for option in options:
|
||||
<option value="${option['value']}">${option['text']}</option>
|
||||
% endfor
|
||||
</optgroup>
|
||||
% endfor
|
||||
% else:
|
||||
<option value="border-all"></option>
|
||||
% for option in item['select_options']:
|
||||
<option value="${option['value']}">${option['text']}</option>
|
||||
% endfor
|
||||
% endif
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">${item['description'] | n}</p>
|
||||
</div>
|
||||
% endif
|
||||
% endfor
|
||||
</div>
|
||||
|
@ -477,26 +504,37 @@
|
|||
plugins: ['remove_button'],
|
||||
persist: false,
|
||||
maxItems: null,
|
||||
valueField: 'email',
|
||||
labelField: 'user',
|
||||
searchField: ['user', 'email'],
|
||||
options: ${json.dumps(user_emails) | n},
|
||||
render: {
|
||||
item: function(item, escape) {
|
||||
return '<div>' +
|
||||
(item.user ? '<span class="user">' + escape(item.user) + '</span>' : '') +
|
||||
(item.email ? '<span class="email">' + escape(item.email) + '</span>' : '') +
|
||||
(item.text ? '<span class="item-text">' + escape(item.text) + '</span>' : '') +
|
||||
(item.value ? '<span class="item-value">' + escape(item.value) + '</span>' : '') +
|
||||
'</div>';
|
||||
},
|
||||
option: function(item, escape) {
|
||||
var label = item.user || item.email;
|
||||
var caption = item.user ? item.email : null;
|
||||
var label = item.text || item.value;
|
||||
var caption = item.text ? item.value : null;
|
||||
if (item.value.endsWith('-all')) {
|
||||
return '<div class="' + item.value + '">' + escape(label) + '</div>'
|
||||
}
|
||||
return '<div>' +
|
||||
escape(label) +
|
||||
(caption ? '<span class="caption">' + escape(caption) + '</span>' : '') +
|
||||
'</div>';
|
||||
}
|
||||
},
|
||||
onItemAdd: function(value) {
|
||||
if (value === 'select-all') {
|
||||
var all_keys = $.map(this.options, function(option){
|
||||
return option.value.endsWith('-all') ? null : option.value;
|
||||
});
|
||||
this.setValue(all_keys);
|
||||
} else if (value === 'remove-all') {
|
||||
this.clear();
|
||||
this.refreshOptions();
|
||||
this.positionDropdown();
|
||||
}
|
||||
},
|
||||
createFilter: function(input) {
|
||||
var match, regex;
|
||||
|
||||
|
@ -514,16 +552,15 @@
|
|||
},
|
||||
create: function(input) {
|
||||
if ((new RegExp('^' + REGEX_EMAIL + '$', 'i')).test(input)) {
|
||||
return {email: input};
|
||||
return {value: input};
|
||||
}
|
||||
var match = input.match(new RegExp('^([^<]*)\<' + REGEX_EMAIL + '\>$', 'i'));
|
||||
if (match) {
|
||||
return {
|
||||
email : match[2],
|
||||
user : $.trim(match[1])
|
||||
value : match[2],
|
||||
text : $.trim(match[1])
|
||||
};
|
||||
}
|
||||
alert('Invalid email address.');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1293,8 +1293,28 @@ class EMAIL(Notifier):
|
|||
logger.error(u"Tautulli Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
|
||||
return False
|
||||
|
||||
def get_user_emails(self):
|
||||
emails = {u['email']: u['friendly_name'] for u in users.Users().get_users() if u['email']}
|
||||
|
||||
user_emails_to = {v: '' for v in self.config['to']}
|
||||
user_emails_cc = {v: '' for v in self.config['cc']}
|
||||
user_emails_bcc = {v: '' for v in self.config['bcc']}
|
||||
|
||||
user_emails_to.update(emails)
|
||||
user_emails_cc.update(emails)
|
||||
user_emails_bcc.update(emails)
|
||||
|
||||
user_emails_to = [{'value': k, 'text': v}
|
||||
for k, v in sorted(user_emails_to.iteritems(), key=lambda x: x[1].lower())]
|
||||
user_emails_cc = [{'value': k, 'text': v}
|
||||
for k, v in sorted(user_emails_cc.iteritems(), key=lambda x: x[1].lower())]
|
||||
user_emails_bcc = [{'value': k, 'text': v}
|
||||
for k, v in sorted(user_emails_bcc.iteritems(), key=lambda x: x[1].lower())]
|
||||
|
||||
return user_emails_to, user_emails_cc, user_emails_bcc
|
||||
|
||||
def return_config_options(self):
|
||||
user_emails = {} # User selection set with selectize options
|
||||
user_emails_to, user_emails_cc, user_emails_bcc = self.get_user_emails()
|
||||
|
||||
config_option = [{'label': 'From Name',
|
||||
'value': self.config['from_name'],
|
||||
|
@ -1312,22 +1332,22 @@ class EMAIL(Notifier):
|
|||
'value': self.config['to'],
|
||||
'name': 'email_to',
|
||||
'description': 'The email address(es) of the recipients.',
|
||||
'input_type': 'select',
|
||||
'select_options': user_emails
|
||||
'input_type': 'selectize',
|
||||
'select_options': user_emails_to
|
||||
},
|
||||
{'label': 'CC',
|
||||
'value': self.config['cc'],
|
||||
'name': 'email_cc',
|
||||
'description': 'The email address(es) to CC.',
|
||||
'input_type': 'select',
|
||||
'select_options': user_emails
|
||||
'input_type': 'selectize',
|
||||
'select_options': user_emails_cc
|
||||
},
|
||||
{'label': 'BCC',
|
||||
'value': self.config['bcc'],
|
||||
'name': 'email_bcc',
|
||||
'description': 'The email address(es) to BCC.',
|
||||
'input_type': 'select',
|
||||
'select_options': user_emails
|
||||
'input_type': 'selectize',
|
||||
'select_options': user_emails_bcc
|
||||
},
|
||||
{'label': 'SMTP Server',
|
||||
'value': self.config['smtp_server'],
|
||||
|
|
|
@ -597,7 +597,7 @@ class Users(object):
|
|||
for item in result:
|
||||
user = {'user_id': item['user_id'],
|
||||
'username': item['username'],
|
||||
'friendly_name': item['friendly_name'],
|
||||
'friendly_name': item['friendly_name'] or item['username'],
|
||||
'email': item['email']
|
||||
}
|
||||
users.append(user)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue