Frontend for invitations.

(imported from commit 8afab7cc5a4a5c14b605f1b27b48036c9414f7d0)
This commit is contained in:
Waseem Daher
2012-12-05 16:48:15 -05:00
committed by Luke Faraone
parent 7a43b4e30b
commit d9e50117be
9 changed files with 152 additions and 1 deletions

View File

@@ -15,6 +15,10 @@
{% rawjstemplate "subscription" %}
</script>
<script id="template_invite_subscription" type="text/x-handlebars-template">
{% rawjstemplate "invite_subscription" %}
</script>
<script id="template_userinfo_popover_title" type="text/x-handlebars-template">
{% rawjstemplate "userinfo_popover_title" %}
</script>
@@ -52,6 +56,7 @@
<script type="text/javascript" src="{{ static_hidden }}js/hotkey.js"></script>
<script type="text/javascript" src="{{ static_hidden }}js/notifications.js"></script>
<script type="text/javascript" src="{{ static_hidden }}js/hashchange.js"></script>
<script type="text/javascript" src="{{ static_hidden }}js/invite.js"></script>
<script type="text/javascript" src="{{ static_hidden }}js/zephyr.js"></script>
{% if debug %}
@@ -132,6 +137,12 @@ var people_list = [
<span class="hidden-phone"> Feedback</span>
</a>
</li>
<li title="Invite users to Humbug">
<a href="#invite-user" role="button" data-toggle="modal">
<i class="icon-gift"></i>
<span class="hidden-phone"> Invite users to Humbug</span>
</a>
</li>
<li title="Log out">
<a href="/accounts/logout">
<i class="icon-off"></i>
@@ -238,5 +249,6 @@ var people_list = [
</div><!--/row-->
{% include "zephyr/keyboard_shortcuts.html" %}
{% include "zephyr/markdown_help.html" %}
{% include "zephyr/invite_user.html" %}
{% endblock %}

View File

@@ -0,0 +1,30 @@
<div class="modal hide" id="invite-user" tabindex="-1" role="dialog"
aria-labelledby="invite-user-label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="invite-user-label">Invite users to Humbug</h3>
</div>
<form id="invite_user_form" class="form-horizontal"
action="/json/invite_users" method="POST">{% csrf_token %}
<div class="modal-body">
<div class="control-group">
<div id="invite-result"></div>
<label class="control-label" for="invitee_emails">Emails (one on each line or comma-separated)</label>
<div class="controls">
<textarea rows="2" id="invitee_emails"
name="invitee_emails"
placeholder="One or more email addresses..."></textarea>
</div>
</div>
<div class="alert" id="invite_status"></div>
<div class="control-group">
<label class="control-label" for="streams_to_add">Streams they should join</label>
<div class="controls" id="streams_to_add"></div>
</div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button class="btn btn-primary" type="submit">Invite</button>
</div>
</form>
</div>

View File

@@ -48,6 +48,9 @@ var globals =
// hashchange.js
+ ' hashchange'
// invite.js
+ ' invite'
// ui.js
+ ' ui'

View File

@@ -0,0 +1,11 @@
{{! Client-side Mustache template for rendering subscriptions in the "invite user" form.}}
<a href="#" onclick="invite.set_all_streams(event, true);">Check all</a> |
<a href="#" onclick="invite.set_all_streams(event, false);">Uncheck all</a>
<div id="stream-checkboxes">
{{#each subscriptions}}
<label class="checkbox">
<input type="checkbox" name="stream" value="{{this}}" checked="true"> {{this}}
</label>
{{/each}}
</div>

View File

@@ -0,0 +1 @@
../../../static/js/invite.js

View File

@@ -0,0 +1,76 @@
var invite = (function () {
var exports = {};
function update_subscription_checkboxes() {
// TODO: If we were more clever, we would only do this if the
// stream list has actually changed; that way, the settings of the
// checkboxes are saved from invocation to invocation (which is
// nice if I want to invite a bunch of people at once)
$('#streams_to_add').html(templates.invite_subscription({subscriptions: stream_list}));
}
exports.initialize = function () {
var invite_status = $('#invite_status');
var invitee_emails = $("#invitee_emails");
var invitee_emails_group = invitee_emails.closest('.control-group');
$('#invite-user').on('show', update_subscription_checkboxes);
invitee_emails.focus();
invitee_emails.autosize();
$("#invite_user_form").ajaxForm({
dataType: 'json',
clearForm: true,
beforeSubmit: function(arr, $form, options) {
invite_status.hide()
.removeClass('alert-error alert-warning alert-success');
invitee_emails_group.removeClass('warning error');
// The array of form data takes the following form:
// [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
// TODO: You could alternatively parse the textarea here, and return errors to
// the user if they don't match certain constraints (i.e. not real email addresses,
// aren't in the right domain, etc.)
//
// OR, you could just let the server do it. Probably my temptation.
return true;
},
success: function (resp, statusText, xhr, form) {
invite_status.text('Users invited successfully.')
.addClass('alert-success')
.show();
},
error: function (xhr, error_type, xhn) {
var arr = $.parseJSON(xhr.responseText);
if (arr.errors === undefined) {
// There was a fatal error, no partial processing occurred.
invite_status.text(arr.msg)
.addClass('alert-error')
.show();
} else {
// Some users were not invited.
var error_list = $('<ul>');
$.each(arr.errors, function (index, value) {
error_list.append($('<li>').text(value.join(': ')));
});
invite_status.addClass('alert-warning')
.empty()
.append($('<p>').text(arr.msg))
.append(error_list)
.show();
invitee_emails_group.addClass('warning');
}
}
});
};
exports.set_all_streams = function (e, val) {
$('#streams_to_add :checkbox').attr('checked', val);
e.preventDefault();
};
return exports;
}());

View File

@@ -16,7 +16,7 @@ $(function () {
// Compile Handlebars templates.
$.each(['message', 'subscription',
'userinfo_popover_title', 'userinfo_popover_content',
'timeinfo_popover_content'],
'timeinfo_popover_content', 'invite_subscription'],
function (index, name) {
templates[name] = Handlebars.compile($('#template_'+name).html());
}

View File

@@ -591,6 +591,7 @@ $(function () {
search.initialize();
notifications.initialize();
hashchange.initialize();
invite.initialize();
$("body").bind('click', function () {
ui.hide_userinfo_popover();

View File

@@ -606,3 +606,20 @@ table.floating_recipient {
width: 140px;
float: right;
}
#invite_user_form {
margin-bottom: 0px;
}
#invitee_emails {
min-height: 40px;
max-height: 300px;
}
#invite_status {
display: none;
}
hr.sidebar {
margin: 0px;
}