add mail interface to users dialog

This commit is contained in:
rolux 2011-12-18 09:27:15 +00:00
parent 1c40048045
commit bea69a918c
10 changed files with 632 additions and 232 deletions

View file

@ -25,7 +25,8 @@
"canSeeDebugMenu": {"staff": true, "admin": true}, "canSeeDebugMenu": {"staff": true, "admin": true},
"canSeeFiles": {"staff": true, "admin": true}, "canSeeFiles": {"staff": true, "admin": true},
"canSeeItem": {"guest": 3, "member": 3, "friend": 4, "staff": 4, "admin": 4}, "canSeeItem": {"guest": 3, "member": 3, "friend": 4, "staff": 4, "admin": 4},
"canSeeExtraItemViews": {"friend": true, "staff": true, "admin": true} "canSeeExtraItemViews": {"friend": true, "staff": true, "admin": true},
"canSendMail": {"staff": true, "admin": true}
}, },
/* /*
clipKeys are the properties that clips can by sorted by. clipKeys are the properties that clips can by sorted by.
@ -549,9 +550,12 @@
], ],
"sendReferrer": false, "sendReferrer": false,
"site": { "site": {
// FIXME: "from" and "to" would be more intuitive as keys here
"email": { "email": {
// E-mail address in contact form (to) // E-mail address in contact form (to)
"contact": "0xdb@0xdb.org", "contact": "0xdb@0xdb.org",
"footer": "-- \n0xDB - http://0xdb.org",
"prefix": "0xDB Newsletter -",
// E-mail address uses by the system (from) // E-mail address uses by the system (from)
"system": "0xdb@0xdb.org" "system": "0xdb@0xdb.org"
}, },

View file

@ -461,6 +461,8 @@
"email": { "email": {
// E-mail address in contact form (to) // E-mail address in contact form (to)
"contact": "pad.ma@pad.ma", "contact": "pad.ma@pad.ma",
"footer": "-- \nPad.ma - http://pad.ma",
"prefix": "Pad.ma Newsletter -",
// E-mail address uses by the system (from) // E-mail address uses by the system (from)
"system": "system@pad.ma" "system": "system@pad.ma"
}, },

View file

@ -135,6 +135,7 @@ class SessionData(models.Model):
'lastseen': self.lastseen, 'lastseen': self.lastseen,
'level': 'guest', 'level': 'guest',
'location': self.location, 'location': self.location,
'newsletter': False,
'notes': '', 'notes': '',
'numberoflists': 0, 'numberoflists': 0,
'screensize': self.screensize, 'screensize': self.screensize,
@ -149,6 +150,7 @@ class SessionData(models.Model):
j['disabled'] = not self.user.is_active j['disabled'] = not self.user.is_active
j['email'] = self.user.email j['email'] = self.user.email
j['level'] = p.get_level() j['level'] = p.get_level()
j['newsletter'] = p.newsletter
j['notes'] = p.notes j['notes'] = p.notes
j['numberoflists'] = self.user.lists.count() j['numberoflists'] = self.user.lists.count()
if keys: if keys:
@ -263,6 +265,7 @@ def init_user(user, request=None):
result['level'] = profile.get_level() result['level'] = profile.get_level()
result['groups'] = [g.name for g in user.groups.all()] result['groups'] = [g.name for g in user.groups.all()]
result['email'] = user.email result['email'] = user.email
result['newsletter'] = profile.newsletter
result['ui'] = profile.get_ui() result['ui'] = profile.get_ui()
result['volumes'] = [v.json() for v in user.volumes.all()] result['volumes'] = [v.json() for v in user.volumes.all()]
return result return result
@ -276,6 +279,7 @@ def user_json(user, keys=None):
'id': ox.to26(user.id), 'id': ox.to26(user.id),
'lastseen': user.last_login, 'lastseen': user.last_login,
'level': p.get_level(), 'level': p.get_level(),
'newsletter': p.newsletter,
'notes': p.notes, 'notes': p.notes,
'numberoflists': user.lists.count(), 'numberoflists': user.lists.count(),
'username': user.username, 'username': user.username,

View file

@ -3,5 +3,4 @@ Subject: {{subject}}
{{message}} {{message}}
-- {{footer}}
{{sitename}} - {{url}}

View file

@ -4,5 +4,4 @@ Subject: {{subject}}
{{message}} {{message}}
-- {{footer}}
{{sitename}} - {{url}}

View file

@ -0,0 +1,4 @@
To: {{to|safe}}
Subject: {{subject|safe}}
{{message|safe}}

View file

@ -4,5 +4,4 @@ To reset your password, please use the following code:
If you don't want to reset your password, no further action is required. If you don't want to reset your password, no further action is required.
-- {{footer}}
{{sitename}} - {{url}}

View file

@ -4,12 +4,11 @@ import random
random.seed() random.seed()
import re import re
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout from django.contrib.auth import authenticate, login, logout
from django.template import RequestContext, loader from django.template import RequestContext, loader
from django.utils import simplejson as json from django.utils import simplejson as json
from django.conf import settings from django.conf import settings
from django.core.mail import send_mail, BadHeaderError from django.core.mail import send_mail, BadHeaderError, EmailMessage
from django.db.models import Sum from django.db.models import Sum
from django.shortcuts import redirect from django.shortcuts import redirect
@ -280,6 +279,7 @@ def requestToken(request):
context = RequestContext(request, { context = RequestContext(request, {
'code': code, 'code': code,
'sitename': settings.SITENAME, 'sitename': settings.SITENAME,
'footer': settings.CONFIG['site']['email']['footer'],
'url': request.build_absolute_uri('/'), 'url': request.build_absolute_uri('/'),
}) })
message = template.render(context) message = template.render(context)
@ -333,6 +333,8 @@ def editUser(request):
profile.set_level(data['level']) profile.set_level(data['level'])
if 'notes' in data: if 'notes' in data:
profile.notes = data['notes'] profile.notes = data['notes']
if 'newsletter' in data:
profile.newsletter = data['newsletter']
if 'username' in data: if 'username' in data:
if models.User.objects.filter(username=data['username']).exclude(id=user.id).count()>0: if models.User.objects.filter(username=data['username']).exclude(id=user.id).count()>0:
response = json_response(status=403, text='username already in use') response = json_response(status=403, text='username already in use')
@ -388,10 +390,10 @@ def findUser(request):
if data['key'] == 'email': if data['key'] == 'email':
response['data']['users'] = [models.user_json(u, keys) response['data']['users'] = [models.user_json(u, keys)
for u in User.objects.filter(email__iexact=data['value'])] for u in models.User.objects.filter(email__iexact=data['value'])]
else: else:
response['data']['users'] = [models.user_json(u, keys) response['data']['users'] = [models.user_json(u, keys)
for u in User.objects.filter(username__iexact=data['value'])] for u in models.User.objects.filter(username__iexact=data['value'])]
return render_to_json_response(response) return render_to_json_response(response)
actions.register(findUser) actions.register(findUser)
@ -527,6 +529,71 @@ Positions
return render_to_json_response(response) return render_to_json_response(response)
actions.register(findUsers) actions.register(findUsers)
@login_required_json
def mail(request):
'''
param data {
'to': array of usernames,
'subject': string,
'message': string
}
message can contain {username} or {email},
this will be replace with the user/email
the mail is sent to.
return {
'status': {'code': int, 'text': string}
}
'''
response = json_response()
data = json.loads(request.POST['data'])
p = request.user.get_profile()
if p.capability('canSendMail'):
email_from = '"%s" <%s>' % (settings.SITENAME, settings.CONFIG['site']['email']['system'])
headers = {
'Reply-To': settings.CONFIG['site']['email']['contact']
}
subject = data.get('subject', '').strip()
users = [models.User.objects.get(username=username) for username in data['to']]
for user in users:
if user.email:
message = data['message']
for key, value in (
('{username}', user.username),
('{email}', user.email),
):
message = message.replace(key, value)
email_to = '"%s" <%s>' % (user.username, user.email)
email = EmailMessage(subject,
message,
email_from,
[email_to],
headers = headers)
email.send(fail_silently=True)
if 'receipt' in data \
and data['receipt']:
template = loader.get_template('mailout_receipt.txt')
context = RequestContext(request, {
'footer': settings.CONFIG['site']['email']['footer'],
'to': ', '.join(['"%s" <%s>' % (u.username, u.email) for u in users]),
'subject': subject,
'message': data['message'],
'url': request.build_absolute_uri('/'),
})
message = template.render(context)
subject = u'Fwd: %s' % subject
email_to = '"%s" <%s>' % (request.user.username, request.user.email)
receipt = EmailMessage(subject,
message,
email_from,
[email_to])
receipt.send(fail_silently=True)
response = json_response(text='message sent')
else:
response = json_response(status=403, text='not allowed to send mail')
return render_to_json_response(response)
actions.register(mail, cache=False)
def contact(request): def contact(request):
''' '''
@ -549,7 +616,7 @@ def contact(request):
if not email: if not email:
email = request.user.email email = request.user.email
if 'message' in data and data['message'].strip(): if 'message' in data and data['message'].strip():
email_from = settings.CONFIG['site']['email']['system'] email_from = '"%s" <%s>' % (settings.SITENAME, settings.CONFIG['site']['email']['system'])
email_to = [settings.CONFIG['site']['email']['contact'], ] email_to = [settings.CONFIG['site']['email']['contact'], ]
subject = data.get('subject', '').strip() subject = data.get('subject', '').strip()
template = loader.get_template('contact_email.txt') template = loader.get_template('contact_email.txt')
@ -559,12 +626,13 @@ def contact(request):
'subject': subject, 'subject': subject,
'message': data['message'].strip(), 'message': data['message'].strip(),
'sitename': settings.SITENAME, 'sitename': settings.SITENAME,
'footer': settings.CONFIG['site']['email']['footer'],
'url': request.build_absolute_uri('/'), 'url': request.build_absolute_uri('/'),
}) })
message = template.render(context) message = template.render(context)
response = json_response(text='message sent') response = json_response(text='message sent')
try: try:
send_mail(u'[%s Contact] %s' % (settings.SITENAME, subject), message, email_from, email_to) send_mail(u'%s Contact - %s' % (settings.SITENAME, subject), message, email_from, email_to)
except BadHeaderError: except BadHeaderError:
response = json_response(status=400, text='invalid data') response = json_response(status=400, text='invalid data')
if request.user.is_authenticated() \ if request.user.is_authenticated() \
@ -575,6 +643,7 @@ def contact(request):
'name': name, 'name': name,
'from': email, 'from': email,
'sitename': settings.SITENAME, 'sitename': settings.SITENAME,
'footer': settings.CONFIG['site']['email']['footer'],
'to': email_to[0], 'to': email_to[0],
'subject': subject, 'subject': subject,
'message': data['message'].strip(), 'message': data['message'].strip(),
@ -618,6 +687,10 @@ def editPreferences(request):
else: else:
change = True change = True
request.user.email = data['email'] request.user.email = data['email']
if 'newsletter' in data:
profile = request.user.get_profile()
profile.newsletter = data['newsletter']
profile.save()
if 'password' in data: if 'password' in data:
change = True change = True
request.user.set_password(data['password']) request.user.set_password(data['password'])

View file

@ -83,6 +83,28 @@ pandora.ui.preferencesDialog = function() {
}) })
); );
} else { } else {
$content.append(
Ox.Checkbox({
checked: pandora.user.newsletter,
id: 'newsletter',
label: 'Newsletter',
labelWidth: 80,
title: pandora.user.newsletter ? 'Subscribed' : 'Unsubscribed',
width: 240
})
.bindEvent({
change: function(data) {
this.options({
title: this.options('title') == 'Subscribed' ? 'Unsubscribed' : 'Subscribed'
});
pandora.user.newsletter = data.checked;
pandora.api.editPreferences({
newsletter: pandora.user.newsletter
});
}
})
.css({position: 'absolute', left: '96px', top: '16px'})
);
$content.append( $content.append(
Ox.Button({ Ox.Button({
title: 'Reset UI Settings', title: 'Reset UI Settings',
@ -94,26 +116,8 @@ pandora.ui.preferencesDialog = function() {
pandora.$ui.appPanel.reload(); pandora.$ui.appPanel.reload();
} }
}) })
.css({position: 'absolute', left: '96px', top: '16px'}) .css({position: 'absolute', left: '96px', top: '46px'})
); );
/*
content.append(Ox.FormElementGroup({
elements: [
Ox.Checkbox({
checked: true ,
id: 'showEpisodes',
title: 'Show Episodes',
width: 320
}),
Ox.Checkbox({
checked: true ,
id: 'newsletter',
title: 'Receive Newsletter',
width: 320
})
]
}));
*/
} }
return $content; return $content;
}, },
@ -127,7 +131,7 @@ pandora.ui.preferencesDialog = function() {
}).bindEvent({ }).bindEvent({
click: function() { click: function() {
$dialog.close(); $dialog.close();
pandora.URL.update(); pandora.UI.set({page: ''});
} }
}) })
], ],

View file

@ -4,8 +4,9 @@
pandora.ui.usersDialog = function() { pandora.ui.usersDialog = function() {
var height = Math.round((window.innerHeight - 48) * 0.9), var dialogHeight = Math.round((window.innerHeight - 48) * 0.9),
width = Math.round(window.innerWidth * 0.9), dialogWidth = Math.round(window.innerWidth * 0.9),
formWidth = 256,
numberOfUsers = 0, numberOfUsers = 0,
userLevels = ['member', 'friend', 'staff', 'admin'], userLevels = ['member', 'friend', 'staff', 'admin'],
@ -77,9 +78,8 @@ pandora.ui.usersDialog = function() {
}, },
id: 'disabled', id: 'disabled',
operator: '-', operator: '-',
title: $('<img>').attr({ title: 'Enabled',
src: Ox.UI.getImageURL('symbolCheck') titleImage: 'check',
}),
visible: true, visible: true,
width: 16 width: 16
}, },
@ -126,6 +126,26 @@ pandora.ui.usersDialog = function() {
visible: true, visible: true,
width: 60 width: 60
}, },
{
format: function(value) {
return $('<img>')
.attr({
src: Ox.UI.getImageURL('symbolMail')
})
.css({
width: '10px',
height: '10px',
padding: '3px',
opacity: +value
});
},
id: 'newsletter',
title: 'Newsletter',
titleImage: 'mail',
operator: '-',
visible: true,
width: 16
},
{ {
id: 'numberoflists', id: 'numberoflists',
align: 'right', align: 'right',
@ -222,7 +242,7 @@ pandora.ui.usersDialog = function() {
columnsVisible: true, columnsVisible: true,
items: pandora.api.findUsers, items: pandora.api.findUsers,
keys: ['notes'], keys: ['notes'],
max: 1, max: -1,
scrollbarVisible: true, scrollbarVisible: true,
sort: [{key: 'lastseen', operator: '-'}] sort: [{key: 'lastseen', operator: '-'}]
}) })
@ -241,33 +261,87 @@ pandora.ui.usersDialog = function() {
) )
); );
}, },
select: function(data) { select: selectUsers
var values;
$user.empty();
if (data.ids.length) {
values = $list.value(data.ids[0]);
if(values.level != 'guest') {
$userLabel.options({
title: values.username + ' &lt;' + values.email + '&gt;'
});
$user.append(renderUserForm(values));
} else {
$userLabel.options({title: 'Guest'});
}
} else {
$userLabel.options({title: 'No user selected'});
}
}
}), }),
$userLabel = Ox.Label({ $formLabel = Ox.Label({
textAlign: 'center', textAlign: 'center',
title: 'No user selected', title: 'No user selected',
width: 248 width: 212
}) })
.css({margin: '4px'}), .css({float: 'left', margin: '4px 2px 4px 4px'}),
$user = Ox.Element({}), $formButton = Ox.ButtonGroup({
buttons: [
{
id: 'edit',
selected: true,
title: 'edit',
tooltip: 'Edit'
},
{
id: 'mail',
title: 'mail',
tooltip: 'Mail'
}
],
selectable: true,
type: 'image'
})
.css({float: 'left', margin: '4px 4px 4px 2px'})
.bindEvent({
change: selectForm
}),
$form = Ox.Element({}),
$editForm,
$mailForm = renderMailForm(),
$content = Ox.SplitPanel({
elements: [
{
element: Ox.SplitPanel({
elements: [
{
element: Ox.Bar({size: 24})
.append($guestsCheckbox)
.append($findElement),
size: 24
},
{
element: $list
}
],
orientation: 'vertical'
})
},
{
element: Ox.SplitPanel({
elements: [
{
element: Ox.Bar({size: 24})
.append($formLabel)
.append($formButton),
size: 24
},
{
element: $form
}
],
orientation: 'vertical'
})
.bindEvent({
resize: setWidth
}),
resizable: true,
resize: [256, 384, 512],
size: 256
}
],
orientation: 'horizontal'
}),
that = Ox.Dialog({ that = Ox.Dialog({
buttons: [ buttons: [
@ -323,51 +397,18 @@ pandora.ui.usersDialog = function() {
}) })
], ],
closeButton: true, closeButton: true,
content: Ox.SplitPanel({ content: $content,
elements: [ height: dialogHeight,
{
element: Ox.SplitPanel({
elements: [
{
element: Ox.Bar({size: 24})
.append($guestsCheckbox)
.append($findElement),
size: 24
},
{
element: $list
}
],
orientation: 'vertical'
})
},
{
element: Ox.SplitPanel({
elements: [
{
element: Ox.Bar({size: 24})
.append($userLabel),
size: 24
},
{
element: $user
}
],
orientation: 'vertical'
}),
size: 256
}
],
orientation: 'horizontal'
}),
height: height,
maximizeButton: true, maximizeButton: true,
minHeight: 256, minHeight: 256,
minWidth: 512, minWidth: 512,
padding: 0, padding: 0,
removeOnClose: true, removeOnClose: true,
title: 'Manage Users', title: 'Manage Users',
width: width width: dialogWidth
})
.bindEvent({
resize: setHeight
}), }),
$status = $('<div>') $status = $('<div>')
@ -383,31 +424,57 @@ pandora.ui.usersDialog = function() {
}) })
.appendTo(that.$element.find('.OxButtonsbar')); .appendTo(that.$element.find('.OxButtonsbar'));
function getFormItemById(id) {
var ret;
Ox.forEach((
$formButton.value() == 'edit' ? $editForm : $mailForm
).options('items'), function($item) {
if ($item.options('id') == id) {
ret = $item;
return false;
}
});
return ret;
};
function renderUserForm(userData) { function getTo() {
var $checkbox; return $list.options('selected').map(function(id) {
return $list.value(id);
}).filter(function(user) {
return user.level != 'guest' && (
$mailForm.values().include == 'users' || user.newsletter
);
}).map(function(user) {
return user.username;
});
}
function renderEditForm() {
var user = $list.value($list.options('selected')[0]);
return Ox.Form({ return Ox.Form({
items: [ items: [
$checkbox = Ox.Checkbox({ Ox.Checkbox({
checked: !userData.disabled, checked: !user.disabled,
id: 'status', id: 'status',
label: 'Status', label: 'Status',
labelWidth: 80, labelWidth: 80,
title: 'Enabled', title: !user.disabled ? 'Enabled' : 'Disabled',
width: 240 width: formWidth - 16
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
// fixme: it would be really nice to have "this" here this.options({
$checkbox.options({title: userData.checked ? 'Enabled' : 'Disabled'}) title: this.options('title') == 'Enabled'
? 'Disabled' : 'Enabled'
});
} }
}), }),
Ox.Input({ Ox.Input({
id: 'username', id: 'username',
label: 'Username', label: 'Username',
labelWidth: 80, labelWidth: 80,
value: userData.username, value: user.username,
width: 240 width: formWidth - 16
}) })
.bindEvent({ .bindEvent({
submit: function(data) { submit: function(data) {
@ -418,8 +485,8 @@ pandora.ui.usersDialog = function() {
id: 'email', id: 'email',
label: 'E-Mail', label: 'E-Mail',
labelWidth: 80, labelWidth: 80,
value: userData.email, value: user.email,
width: 240 width: formWidth - 16
}) })
.bindEvent({ .bindEvent({
submit: function(data) { submit: function(data) {
@ -430,27 +497,38 @@ pandora.ui.usersDialog = function() {
id: 'level', id: 'level',
items: userLevels.map(function(level) { items: userLevels.map(function(level) {
return { return {
checked: level == userData.level, checked: level == user.level,
id: level, id: level,
title: Ox.toTitleCase(level) title: Ox.toTitleCase(level)
}; };
}), }),
label: 'Level', label: 'Level',
labelWidth: 80, labelWidth: 80,
width: 240 width: formWidth - 16
}), }),
/* Ox.Checkbox({
Ox.Label({ checked: user.newsletter,
title: 'Notes' id: 'newsletter',
label: 'Newsletter',
labelWidth: 80,
title: user.newsletter ? 'Subscribed' : 'Unsubscribed',
width: formWidth - 16
})
.bindEvent({
change: function(data) {
this.options({
title: this.options('title') == 'Subscribed'
? 'Unsubscribed' : 'Subscribed'
});
}
}), }),
*/
Ox.Input({ Ox.Input({
height: 120, height: dialogHeight - 160,
id: 'notes', id: 'notes',
placeholder: 'Notes', placeholder: 'Notes',
type: 'textarea', type: 'textarea',
value: userData.notes, value: user.notes,
width: 240 width: formWidth - 16
}) })
], ],
width: 240 width: 240
@ -458,15 +536,17 @@ pandora.ui.usersDialog = function() {
.css({margin: '8px'}) .css({margin: '8px'})
.bindEvent({ .bindEvent({
change: function(event) { change: function(event) {
var data = {id: userData.id}, key, value; var data = {id: user.id}, key, value;
if (event.id == 'status') { if (event.id == 'status') {
data.disabled = !event.data.checked; data.disabled = !event.data.checked;
} else if (event.id == 'level') { } else if (event.id == 'level') {
data.level = event.data.selected[0].id; data.level = event.data.selected[0].id;
} else if (event.id == 'newsletter') {
data.newsletter = event.data.checked;
} else { } else {
data[event.id] = event.data.value; data[event.id] = event.data.value;
} }
$list.value(userData.id, event.id, data[event.id]); $list.value(user.id, event.id, data[event.id]);
pandora.api.editUser(data, function(result) { pandora.api.editUser(data, function(result) {
Ox.Request.clearCache('findUsers'); Ox.Request.clearCache('findUsers');
}); });
@ -474,6 +554,238 @@ pandora.ui.usersDialog = function() {
}); });
} }
function renderMailForm() {
return Ox.Form({
items: [
Ox.Input({
disabled: true,
id: 'from',
label: 'From',
labelWidth: 80,
value: pandora.site.site.name + ' <' + pandora.site.site.email.contact + '>',
width: formWidth - 16
}),
Ox.Input({
disabled: true,
id: 'to',
label: 'To',
labelWidth: 80,
value: '',
width: formWidth - 16
}),
Ox.Select({
id: 'include',
items: [
{id: 'users', title: 'All users'},
{id: 'subscribers', title: 'Subscribers only'},
],
label: 'Include',
labelWidth: 80,
width: formWidth - 16
})
.bindEvent({
change: function() {
setTo();
setSend();
}
}),
Ox.Input({
id: 'subject',
label: 'Subject',
labelWidth: 80,
value: pandora.site.site.email.prefix + ' ',
width: formWidth - 16
})
.bindEvent({
change: setSend
}),
Ox.Input({
height: dialogHeight - 208,
id: 'message',
placeholder: 'Message',
type: 'textarea',
value: '\n\n' + pandora.site.site.email.footer,
width: formWidth - 16
})
.bindEvent({
change: setSend
}),
Ox.Select({
id: 'insert',
items: [
{id: 'username', title: 'Username'},
{id: 'email', title: 'E-Mail address'},
],
selectable: false,
title: 'Insert...',
width: formWidth - 16
})
.bindEvent({
click: function(data) {
var $input = getFormItemById('message'),
textarea = $input.find('textarea')[0],
value = $input.options('value');
$input.options({
value: value.substr(0, textarea.selectionStart)
+ '{' + data.id + '}'
+ value.substr(textarea.selectionEnd)
})
.focusInput(textarea.selectionStart + data.id.length + 2);
}
}),
Ox.Checkbox({
checked: false,
id: 'receipt',
title: 'Send a receipt to ' + pandora.user.email,
width: formWidth - 16
}),
Ox.Button({
disabled: true,
id: 'send',
title: 'Send',
width: 64
})
.bindEvent({
click: sendMail
})
],
width: formWidth - 16
})
.css({margin: '8px', textAlign: 'right'});
}
function selectForm(data) {
var selected;
if (data.selected[0] == 'edit') {
$mailForm.detach();
selected = $list.options('selected');
if (selected.length == 1 && selected[0].level != 'guest') {
$form.append($editForm = renderEditForm());
}
} else {
setTo();
setSend();
setWidth();
$editForm && $editForm.remove();
$form.append($mailForm);
}
}
function selectUsers(data) {
var users = $list.options('selected').map(function(id) {
return $list.value(id);
});
setLabel();
if ($formButton.value() == 'edit') {
$form.empty();
if (data.ids.length == 1) {
if (users[0].level != 'guest') {
$form.append($editForm = renderEditForm());
}
}
} else {
setTo();
setSend();
}
}
function sendMail() {
pandora.api.mail({
to: getTo(),
subject: getFormItemById('subject').options('value'),
message: getFormItemById('message').options('value'),
receipt: getFormItemById('receipt').value()
}, function(result) {
var title = result.status.code == 200
? 'Message Sent'
: 'Application Error',
message = result.status.code == 200
? 'Your message has been sent.'
: 'Your message could not be sent. Please try again.',
$dialog = Ox.Dialog({
buttons: [
Ox.Button({
id: 'close',
title: 'Close'
})
.bindEvent({
click: function() {
$dialog.close();
}
})
],
// FIXME: we need a template for this type of dialog
content: Ox.Element()
.append(
$('<img>')
.attr({src: '/static/png/icon64.png'})
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
)
.append(
$('<div>')
.css({position: 'absolute', left: '96px', top: '16px', width: '192px'})
.html(message)
),
height: 128,
keys: {enter: 'close', escape: 'close'},
removeOnClose: true,
title: title,
width: 304
}).open();
});
}
function setHeight(data) {
var form = $formButton.options('value'),
$item = getFormItemById(form == 'edit' ? 'notes' : 'message');
Ox.print('$ITEM', $item)
dialogHeight = data.height;
$item && $item.options({
height: dialogHeight - (form == 'edit' ? 160 : 208)
});
}
function setLabel() {
var users = $list.options('selected').map(function(id) {
return $list.value(id);
}),
title = users.length == 0 ? 'No user selected'
: users.length == 1 ? (
users[0].level == 'guest'
? 'Guest'
: users[0].username + ' &lt;' + users[0].email + '&gt;'
)
: users.length + ' users selected';
$formLabel.options({title: title});
}
function setSend() {
getFormItemById('send').options({
disabled: getFormItemById('to').options('value') == 'No recipients'
|| getFormItemById('subject').options('value') === ''
|| getFormItemById('message').options('value') === ''
});
}
function setTo() {
var recipients = getTo().length;
$mailForm.values({
to: (recipients || 'No') + ' recipient' + (recipients == 1 ? '' : 's')
});
}
function setWidth() {
formWidth = $content.size(1);
$formLabel.options({width: formWidth - 44});
(
$formButton.value() == 'edit' ? $editForm : $mailForm
).options('items').forEach(function($item) {
if ($item.options('id') != 'send') {
$item.options({width: formWidth - 16});
}
});
}
function updateList() { function updateList() {
var guests = $guestsCheckbox.value(), var guests = $guestsCheckbox.value(),
key = $findSelect.value(), key = $findSelect.value(),