aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--templates/web/fixmybarangay/around/tabbed_lists.html68
-rw-r--r--templates/web/fixmybarangay/header.html4
-rw-r--r--templates/web/fixmybarangay/report/_message_manager.html137
-rw-r--r--web/cobrands/fixmybarangay/message_manager.scss64
-rw-r--r--web/cobrands/fixmybarangay/message_manager_client.js193
5 files changed, 346 insertions, 120 deletions
diff --git a/templates/web/fixmybarangay/around/tabbed_lists.html b/templates/web/fixmybarangay/around/tabbed_lists.html
index 77ca84ee4..14461628c 100644
--- a/templates/web/fixmybarangay/around/tabbed_lists.html
+++ b/templates/web/fixmybarangay/around/tabbed_lists.html
@@ -14,71 +14,5 @@ IF allow_creation %]
</ul>
[% IF allow_creation %]
-<ul id="message_manager" class="issue-list-a tab">
- <li id="message-control">
- <div id="mm-username-container">username:&nbsp;<span id="mm-received-username"></span></div>
- <div id="mm-status-message-container">
- <div id="mm-status-message"></div>
- </div>
- <div id="mm-login-container">
- <div class="input text">
- <label for="mm-htauth-username">MM username</label>
- <input name="mm-htauth-username" id="mm-htauth-username" type="text"/>
- </div>
- <div class="input password">
- <label for="mm-htauth-password">Password</label>
- <input name="mm-htauth-password" id="mm-htauth-password" type="password"/>
- </div>
- <div class="submit">
- <input id="available-submit" type="submit" value="Get available messages"/>
- </div>
- </div>
- </li>
- <li>
- <div id="mm-message-list" style="min-height:1em;"></div>
- </li>
-</ul>
-
-<script type="text/javascript">
-
-$(document).ready(function() {
-
- var mm_url = "[% c.config.MESSAGE_MANAGER_URL %]"; // from config
-
- var mm_populate_list = function(data) {
- $('#mm-status-message-container').text("Accessed message server as " + data['username']);
- $('input[name=mm_text]').prop('checked', false); // uncheck all
- }
-
- var mm_selected_message = function(data) {
- var msg_text = "";
- var service_id = "";
- if (data['success']) {
- // msg_text = $('#form_detail').val( $('input[name=mm_text]:checked').val() ); # == message data
- msg_text = data['data']['Message']['message'];
- service_id = data['data']['Message']['id'];
- } else {
- $('input[name=mm_text]').prop('checked', false); // uncheck all
- }
- $('#form_detail').val(msg_text);
- $('#external_source_id').val(service_id);
- }
-
- message_manager.config({url_root: mm_url});
- message_manager.setup_click_listener({callback:mm_selected_message});
-
- // problem form hidden input "external_source_id": pass the MM id into FMS, if used
- $('<input type="hidden"/>').attr({
- 'id': 'external_source_id',
- 'name': 'external_source_id',
- }).appendTo($('#problem_form'));
-
- $('#available-submit').click(function(e){
- e.preventDefault();
- message_manager.get_available_messages({callback:mm_populate_list});
- });
- $('#available-submit').click();
-});
-
-</script>
+ [% TRY %][% INCLUDE 'report/_message_manager.html' %][% CATCH file %][% END %]
[% END %]
diff --git a/templates/web/fixmybarangay/header.html b/templates/web/fixmybarangay/header.html
index 2b2f031e2..c3ddd154e 100644
--- a/templates/web/fixmybarangay/header.html
+++ b/templates/web/fixmybarangay/header.html
@@ -25,6 +25,10 @@
[% allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_council); %]
[% IF allow_creation %]
+
+ <link rel="stylesheet" href="[% version('/js/fancybox/jquery.fancybox-1.3.4.css') %]">
+ <script src="[% version('/js/fancybox/jquery.fancybox-1.3.4.pack.js') %]" charset="utf-8"></script>
+
<script src="[% version('/cobrands/fixmybarangay/message_manager_client.js') %]" charset="utf-8"></script>
<script>
$(document).ready(function() {
diff --git a/templates/web/fixmybarangay/report/_message_manager.html b/templates/web/fixmybarangay/report/_message_manager.html
index 2697e156c..9f3692f17 100644
--- a/templates/web/fixmybarangay/report/_message_manager.html
+++ b/templates/web/fixmybarangay/report/_message_manager.html
@@ -1,6 +1,9 @@
[% IF c.user && c.user.from_council %]
-<input type="button" class="green-btn" value="Show Messages" id="show_messages">
+[% IF problem.id %]
+ <input type="button" class="green-btn" value="Show Messages" id="show_messages">
+[% END %]
+
<ul id="message_manager" class="issue-list-a tab" style="display: none">
<li id="message-control">
<div id="mm-username-container">username:&nbsp;<span id="mm-received-username"></span></div>
@@ -8,16 +11,16 @@
<div id="mm-status-message"></div>
</div>
<div id="mm-login-container">
- <div class="input text">
- <label for="mm-htauth-username">MM username</label>
+ <div>
+ <label for="mm-htauth-username">Username:</label>
<input name="mm-htauth-username" id="mm-htauth-username" type="text"/>
</div>
- <div class="input password">
- <label for="mm-htauth-password">Password</label>
+ <div>
+ <label for="mm-htauth-password">Password:</label>
<input name="mm-htauth-password" id="mm-htauth-password" type="password"/>
</div>
<div class="submit">
- <input id="available-submit" type="submit" value="Get available messages"/>
+ <input id="available-submit" type="submit" value="Get available messages" class="green-btn"/>
</div>
</div>
</li>
@@ -25,15 +28,35 @@
<div id="mm-message-list" style="min-height:1em;"></div>
</li>
</ul>
+<div style="display:none">
+ <div id="reply-form-container">
+ <form action="/" id="reply-form" onsubmit="event.returnValue = false; return false;" method="post" accept-charset="utf-8">
+ <input type="hidden" name="message_id" id="reply_to_msg_id"/>
+ <div>
+ <label for="reply_text">Reply text:</label>
+ <textarea name="reply_text" id="reply_text"></textarea>
+ </div>
+ <div class="submit">
+ <input id="reply-submit" type="submit" value="Send Reply" class="green-btn"/>
+ </div>
+ </form>
+ </div>
+</div>
<script type="text/javascript">
$(document).ready(function() {
var mm_url = "[% c.config.MESSAGE_MANAGER_URL %]"; // from config
-
+ var problem_id = "[% problem.id %]";
+ var dummy_busy = false;
+
+ function sanitise_id(css_id) {
+ return css_id.replace(/\D/g, "");
+ }
+
var mm_populate_list = function(data) {
- $('#mm-status-message-container').text("Accessed message server as " + data['username']);
+ $('#mm-status-message-container').text("Accessed Message Manager as " + data['username']);
$('input[name=mm_text]').prop('checked', false); // uncheck all
}
@@ -50,6 +73,15 @@ $(document).ready(function() {
$('#form_detail').val(msg_text);
$('#external_source_id').val(service_id);
}
+
+ var dummy_reply_cleanup = function(data) {
+ $('#reply_text').val('');
+ dummy_busy = false;
+ }
+
+ var dummy_hide_cleanup = function(data) {
+ dummy_busy = false;
+ }
message_manager.config({url_root: mm_url});
message_manager.setup_click_listener({callback:mm_selected_message});
@@ -66,29 +98,76 @@ $(document).ready(function() {
});
$('#available-submit').click();
- $('<input type="button" value="Copy to update"/>').attr({
- 'id': 'add_support',
- 'name': 'add_support',
- 'class': 'green-btn'
- }).appendTo($('#message_manager'));
+ $('#hide-button').click(function() {
+ if ($('#message_id').val()) {
+ message_manager.hide(
+ $('#message_id').val(),
+ {callback:dummy_hide_cleanup});
+ }
+ });
+
+ $('#mm-message-list').on('mouseover', 'li.mm-msg', function(e){
+ e.stopPropagation(); // because replies are nested
+ $('.mm-msg-action', $('#mm-message-list')).stop().fadeOut(200);
+ $(this).find('> .mm-msg-action').stop().show();
+ console.log("clicked on: " + $(this).attr('id'));
+ });
+
+ $('#mm-message-list').on('click', '.mm-hide', function(e){
+ var want_hide =
+ confirm('Are you sure you want to delete the following message?\n\n"'
+ + $('p', $(this).parent()).first().text() + '"\n');
+ if (want_hide) {
+ message_manager.hide(
+ sanitise_id($(this).parent().attr('id')),
+ {callback:dummy_hide_cleanup});
+ }
+ });
+
+ $('#mm-message-list').on('click', '.mm-rep', function(e){
+ console.log("call message_manager.reply(" + $(this).parent().attr('id') + ", reply_text)");
+ });
+
+ $('#reply-submit').click(function(e) {
+ e.preventDefault();
+ if (! dummy_busy) {
+ dummy_busy = true;
+ console.log("sending reply to: " + $('#reply_to_msg_id').val());
+ message_manager.reply(
+ $('#reply_to_msg_id').val(),
+ $('#reply_text').val(),
+ {callback:dummy_reply_cleanup});
+ }
+ });
+
+ $("a#reply").fancybox({onClosed: function(){dummy_busy=false;}});
+
+ // only show on problem display page
+ if (problem_id) {
+ $('<input type="button" value="Copy to update"/>').attr({
+ 'id': 'add_support',
+ 'name': 'add_support',
+ 'class': 'green-btn'
+ }).appendTo($('#message_manager'));
+ }
$('#add_support').click(function(e){
- e.preventDefault();
- $('#mm-message-list input:checked').each( function(index) {
- var id = $(this).attr('id');
- id = id.replace('mm_text_','');
- $('#external_source_id').val(id);
- $('#form_update').val( $(this).val() );
- $('#form_update_form').on('submit', function(e) {
- message_manager.assign_fms_id( $('#external_source_id').val(), [% problem.id %], { 'is_async': false } );
- });
- });
- });
-
- $('#show_messages').on('click', function(e) {
- $('#message_manager').toggle();
- $('#show_messages').val( $('#show_messages').val() == 'Show Messages' ? 'Hide Messages' : 'Show Messages' );
- } );
+ e.preventDefault();
+ $('#mm-message-list input:checked').each( function(index) {
+ var id = $(this).attr('id');
+ id = id.replace('mm_text_','');
+ $('#external_source_id').val(id);
+ $('#form_update').val( $(this).val() );
+ $('#form_update_form').on('submit', function(e) {
+ message_manager.assign_fms_id( $('#external_source_id').val(), problem_id, { 'is_async': false } );
+ });
+ });
+ });
+
+ $('#show_messages').on('click', function(e) {
+ $('#message_manager').toggle();
+ $('#show_messages').val( $('#show_messages').val() == 'Show Messages' ? 'Hide Messages' : 'Show Messages' );
+ });
});
</script>
diff --git a/web/cobrands/fixmybarangay/message_manager.scss b/web/cobrands/fixmybarangay/message_manager.scss
index 3133d3bbc..5b6d7bd62 100644
--- a/web/cobrands/fixmybarangay/message_manager.scss
+++ b/web/cobrands/fixmybarangay/message_manager.scss
@@ -1,6 +1,16 @@
$mm_status_message_color: #a66;
$mm_border_color: #eee;
+$color_reply_bg: #cccccc;
+$color_bg_reply_0: #E8E8E8;
+$color_bg_reply_1: #DEDEDE;
+$color_bg_reply_2: #D6D6D6;
+$color_bg_reply_3: #D1D1D1;
+$color_bg_reply_4: #C9C9C9;
+$color_bg_reply_5: #BFBFBF;
+$color_bg_reply_6: #B8B8B8;
+$color_bg_mm_list: #F6F6F6;
+
#message_manager {
#message-control {
@@ -38,14 +48,34 @@ $mm_border_color: #eee;
list-style-type: none;
padding: 0;
margin: 0;
- li {
+ li, ul.mm-reply-thread li {
+ position: relative;
clear: both;
margin: 4px 0 0 0;
padding: 0;
cursor: pointer;
- background-color: #F6F6F6;
+ background-color: $color_bg_mm_list;
p {
background-color: inherit;
+ margin: 0.25em 0 0 0;
+ padding: 0.5em 1em;
+ &:hover { background-color: #efe;}
+ }
+ ul.mm-reply-thread {
+ li {
+ margin:0;
+ }
+ .mm-reply {
+ background-color: #ccc;
+ &:hover {background-color: #eef;}
+ }
+ .mm-reply-0 { margin-left: 0em; background-color: $color_bg_reply_0;}
+ .mm-reply-1 { margin-left: 1em; background-color: $color_bg_reply_1;}
+ .mm-reply-2 { margin-left: 2em; background-color: $color_bg_reply_2;}
+ .mm-reply-3 { margin-left: 3em; background-color: $color_bg_reply_3;}
+ .mm-reply-4 { margin-left: 4em; background-color: $color_bg_reply_4;}
+ .mm-reply-5 { margin-left: 5em; background-color: $color_bg_reply_5;}
+ .mm-reply-6 { margin-left: 6em; background-color: $color_bg_reply_6;}
}
&.msg-is-locked { background-color: #fdd;}
&.msg-is-owned { background-color: #dfd;}
@@ -64,6 +94,23 @@ $mm_border_color: #eee;
font-weight: normal;
margin: 0.1em 0 0.1em 4.5em;
}
+ .mm-msg-action {
+ display: none;
+ padding: 0.2em 0.4em;
+ color: white;
+ text-align: center;
+ position: absolute;
+ top: 4px;
+ &:hover { background-color: black;}
+ }
+ .mm-hide {
+ right:0px;
+ background-color: red;
+ }
+ .mm-rep {
+ right:1.4em;
+ background-color: green;
+ }
}
}
}
@@ -71,3 +118,16 @@ $mm_border_color: #eee;
margin: 1em;
}
}
+#show_messages, #add_support { // COPY TO UPDATE button
+ margin: 1em;
+}
+#reply-form-container {
+ #reply-form{
+ margin-top: 2em;
+ border: 1px solid $mm_border_color;
+ background-color: #ffdddd;
+ }
+ .submit {
+ margin: 1em 0;
+ }
+}
diff --git a/web/cobrands/fixmybarangay/message_manager_client.js b/web/cobrands/fixmybarangay/message_manager_client.js
index 508286171..1614eff2d 100644
--- a/web/cobrands/fixmybarangay/message_manager_client.js
+++ b/web/cobrands/fixmybarangay/message_manager_client.js
@@ -14,6 +14,9 @@
*
* msg_prefix all message <li> items have this as their ID prefix
*
+ * mm_name name of Message Manager (used in error messages shown
+ * to user, e.g., "please log in to Message Manager"
+ *
* *_selector these are the jQuery selects that will be used to find
* the respective elements:
*
@@ -28,6 +31,8 @@
* message_manager.get_available_messages([options])
* message_manager.request_lock(msg_id, [options]) (default use: client code doesn't need to call this explicitly)
* message_manager.assign_fms_id(msg_id, fms_id, [options])
+ * message_manager.hide(msg_id, [options])
+ * message_manager.reply(msg_id, reply_text, [options])
*
* Note: options are {name:value, ...} hashes and often include "callback" which is a function that is executed on success
* but see the docs (request_lock executes callback if the call is successful even if the lock was denied, for example).
@@ -42,7 +47,9 @@ var message_manager = (function() {
var _want_unique_locks = true;
var _msg_prefix = "msg-";
var _username;
-
+ var _mm_name = "Message Manager";
+ var _use_fancybox = true; // note: currently *must* have fancybox!
+
// cached jQuery elements, populated by the (mandatory) call to config()
var $message_list_element;
var $status_element;
@@ -77,6 +84,9 @@ var message_manager = (function() {
selectors[sel] = settings[sel];
}
}
+ if (typeof settings.mm_name === 'string') {
+ _mm_name = settings.mm_name;
+ }
}
$message_list_element = $(selectors.message_list_selector);
$status_element = $(selectors.status_selector);
@@ -131,6 +141,57 @@ var message_manager = (function() {
}
};
+ var extract_replies = function(replies, depth) {
+ var $ul = "";
+ if (replies && replies.length > 0) {
+ var indent = new Array( depth + 1 ).join('&nbsp;');
+ $ul = $('<ul class="mm-reply-thread"/>');
+ for (var i=0; i<replies.length; i++) {
+ $ul.append(get_message_li(replies[i], depth));
+ }
+ }
+ return $ul;
+ }
+
+ var get_message_li = function(message_root, depth) {
+ var msg = message_root.Message; // or use label value
+ var lockkeeper = message_root.Lockkeeper.username;
+ var escaped_text = $('<div/>').text(msg.message).html();
+ var $p = $('<p/>');
+ var $hide_button = $('<span class="mm-msg-action mm-hide" id="mm-hide-' + msg.id + '">X</span>');
+ var $reply_button = $('<a class="mm-msg-action mm-rep" id="mm-rep-' + msg.id + '" href="#reply-form-container">reply</a>');
+ if (_use_fancybox) {
+ $reply_button.fancybox();
+ }
+ if (depth == 0) {
+ var tag = (!msg.tag || msg.tag === 'null')? '&nbsp;' : msg.tag;
+ tag = $('<span class="msg-tag"/>').html(tag);
+ var radio = depth > 0? null : $('<input type="radio"/>').attr({
+ 'id': 'mm_text_' + msg.id,
+ 'name': 'mm_text',
+ 'value': escaped_text
+ }).wrap('<p/>').parent().html();
+ var label = $('<label/>', {
+ 'class': 'msg-text',
+ 'for': 'mm_text_' + msg.id
+ }).text(escaped_text).wrap('<p/>').parent().html();
+ $p.append(tag).append(radio).append(label);
+ } else {
+ $p.text(escaped_text).addClass('mm-reply mm-reply-' + depth);
+ }
+ var $litem = $('<li id="' + _msg_prefix + msg.id + '" class="mm-msg">').append($p).append($hide_button)
+ if (msg.is_outbound != 1) {
+ $litem.append($reply_button);
+ };
+ if (lockkeeper) {
+ $litem.addClass(lockkeeper == _username? 'msg-is-owned' : 'msg-is-locked');
+ }
+ if (message_root.children) {
+ $litem.append(extract_replies(message_root.children, depth+1));
+ }
+ return $litem;
+ }
+
var show_available_messages = function(data) {
var messages = data.messages;
_username = data.username;
@@ -139,27 +200,9 @@ var message_manager = (function() {
if (messages.length === 0) {
$output.html('<p class="mm-empty">No messages available.</p>');
} else {
- var $ul = $('<ul/>');
+ var $ul = $('<ul class="mm-root"/>');
for(var i=0; i< messages.length; i++) {
- var msg = messages[i].Message; // or use label value
- var lockkeeper = messages[i].Lockkeeper.username;
- var escaped_text = $('<div/>').text(msg.message).html();
- var tag = (!msg.tag || msg.tag === 'null')? '&nbsp;' : msg.tag;
- tag = $('<span class="msg-tag"/>').html(tag);
- var radio = $('<input type="radio"/>').attr({
- 'id': 'mm_text_' + msg.id,
- 'name': 'mm_text',
- 'value': escaped_text
- }).wrap('<p/>').parent().html();
- var label = $('<label/>', {
- 'class': 'msg-text',
- 'for': 'mm_text_' + msg.id
- }).text(escaped_text).wrap('<p/>').parent().html();
- var p = $('<p/>').append(tag).append(radio).append(label);
- var litem = $('<li id="' + _msg_prefix + msg.id + '" class="mm-msg">').append(p);
- if (lockkeeper) {
- litem.addClass(lockkeeper == _username? 'msg-is-owned' : 'msg-is-locked');
- }
+ var litem = get_message_li(messages[i], 0);
$ul.append(litem);
}
$output.empty().append($ul);
@@ -185,6 +228,10 @@ var message_manager = (function() {
}
request_lock(id, options);
});
+ // clicking the reply button loads the id into the (modal/fancybox) reply form
+ $message_list_element.on('click', '.mm-rep', function(event) {
+ $('#reply_to_msg_id').val($(this).closest('li').attr('id').replace(_msg_prefix, ''));
+ })
};
// gets messages or else requests login
@@ -217,7 +264,8 @@ var message_manager = (function() {
error: function(jqXHR, textStatus, errorThrown) {
var st = jqXHR.status;
if (st == 401 || st == 403) {
- var msg = (st == 401)? "Invalid username or password" : "Access denied: please log in";
+ var msg = (st == 401 ? "Invalid username or password for" : "Access denied: please log in to")
+ + " " + _mm_name;
say_status(msg);
show_login_form();
} else {
@@ -333,6 +381,105 @@ var message_manager = (function() {
});
};
+ var reply = function(msg_id, reply_text, options) {
+ if (_use_fancybox){
+ $.fancybox.close();
+ }
+ var check_li_exists = false;
+ if (options) {
+ if (typeof(options.callback) === 'function') {
+ callback = options.callback;
+ }
+ if (typeof(options.check_li_exists) !== undefined && options.check_li_exists !== undefined) {
+ check_li_exists = true; // MM dummy
+ }
+ }
+ var $li = $('#' + _msg_prefix + msg_id);
+ if (check_li_exists) {
+ if ($li.size() === 0) {
+ say_status("Couldn't find message with ID " + msg_id);
+ return;
+ }
+ }
+ reply_text = $.trim(reply_text);
+ if (reply_text === '') {
+ say_status("won't send empty reply");
+ return;
+ }
+ $li.addClass('msg-is-busy');
+ $.ajax({
+ dataType:"json",
+ type:"post",
+ data: {reply_text: reply_text},
+ url: _url_root +"messages/reply/" + msg_id + ".json",
+ beforeSend: function (xhr){
+ xhr.setRequestHeader('Authorization', get_current_auth_credentials());
+ xhr.withCredentials = true;
+ },
+ success:function(data, textStatus) {
+ if (data.success) {
+ $li.removeClass('msg-is-busy msg-is-locked').addClass('msg-is-owned'); // no longer available
+ say_status("Reply sent OK");
+ if (typeof(callback) === "function") {
+ callback.call($(this), data.data); // returned data['data'] is null but may change in future
+ }
+ } else {
+ $li.removeClass('msg-is-busy').addClass('msg-is-locked');
+ say_status("failed: " + data.error);
+ }
+ },
+ error: function(jqXHR, textStatus, errorThrown) {
+ say_status("error: " + textStatus + ": " + errorThrown);
+ $li.removeClass('msg-is-busy');
+ }
+ });
+ };
+
+ var hide = function(msg_id, options) {
+ var check_li_exists = false;
+ if (options) {
+ if (typeof(options.callback) === 'function') {
+ callback = options.callback;
+ }
+ if (typeof(options.check_li_exists) !== undefined && options.check_li_exists !== undefined) {
+ check_li_exists = true; // MM dummy
+ }
+ }
+ var $li = $('#' + _msg_prefix + msg_id);
+ if (check_li_exists) {
+ if ($li.size() === 0) {
+ say_status("Couldn't find message with ID " + msg_id);
+ return;
+ }
+ }
+ $li.addClass('msg-is-busy');
+ $.ajax({
+ dataType:"json",
+ type:"post",
+ url: _url_root +"messages/hide/" + msg_id + ".json",
+ beforeSend: function (xhr){
+ xhr.setRequestHeader('Authorization', get_current_auth_credentials());
+ xhr.withCredentials = true;
+ },
+ success:function(data, textStatus) {
+ if (data.success) {
+ $li.removeClass('msg-is-busy msg-is-locked').addClass('msg-is-owned').fadeOut('slow'); // no longer available
+ say_status("Message hidden");
+ if (typeof(callback) === "function") {
+ callback.call($(this), data.data);
+ }
+ } else {
+ $li.removeClass('msg-is-busy').addClass('msg-is-locked');
+ say_status("failed: " + data.error);
+ }
+ },
+ error: function(jqXHR, textStatus, errorThrown) {
+ say_status("error: " + textStatus + ": " + errorThrown);
+ $li.removeClass('msg-is-busy');
+ }
+ });
+ };
+
// revealed public methods:
return {
config: config,
@@ -340,6 +487,8 @@ var message_manager = (function() {
get_available_messages: get_available_messages,
request_lock: request_lock,
assign_fms_id: assign_fms_id,
+ reply: reply,
+ hide: hide,
sign_out: sign_out
};
})();