version 1 of the inbox search

This commit is contained in:
Alexandre Cloutier committed 2014-08-06 14:49:36 -04:00
1 parent 1cc93c700a
commit 7794d716b9
16 files changed
+891 -82

No files matched your search

+60 -14
View File
@@ -432,6 +432,38 @@ function onDocumentKeydown(event) {
}
}
/* Search mail, call the template and open inside a dialog windoƒw */
function onSearchMail(event) {
if ($("searchMailView")) {
$("searchMailView").style.display = "block";
$("bgDialogDiv").style.display = "block";
initSearchMailView();
}
else {
var urlstr = ApplicationBaseURL + "/search";
// Return the template for the searchMail feature
triggerAjaxRequest(urlstr, displaySearchMailCallback);
}
}
function displaySearchMailCallback(http) {
if (http.readyState == 4 && http.status == 200) {
var fields = createElement("div", null); // (tagName, id, classes, attributes, htmlAttributes, parentNode)
var title = _("Search mail");
var id = _("searchMailView");
fields.innerHTML = http.responseText;
dialog = createDialog(id, title, null, fields, "searchMail"); // (id, title, legend, content, positionClass)
document.body.appendChild(dialog);
if (Prototype.Browser.IE)
jQuery('#bgDialogDiv').css('opacity', 0.4);
jQuery(dialog).fadeIn('fast');
initSearchMailView();
}
}
/* bulk delete of messages */
function deleteSelectedMessages(sender) {
@@ -780,7 +812,7 @@ function composeNewMessage() {
function openMailbox(mailbox, reload) {
if (mailbox != Mailer.currentMailbox || reload) {
var url = ApplicationBaseURL + encodeURI(mailbox.unescapeHTML());
var urlParams = new Hash();
var urlParams = {};
if (!reload) {
var messageContent = $("messageContent");
@@ -791,13 +823,28 @@ function openMailbox(mailbox, reload) {
var searchValue = search["mail"]["value"];
if (searchValue && searchValue.length > 0) {
urlParams.set("search", search["mail"]["criteria"]);
urlParams.set("value", escape(searchValue.utf8encode()));
var searchCriteria = [];
if (search["mail"]["criteria"] == "subject")
searchCriteria.push("subject");
else if (search["mail"]["criteria"] == "sender")
searchCriteria.push("from");
else if (search["mail"]["criteria"] == "subject_or_sender")
searchCriteria.push("subject", "from");
else if (search["mail"]["criteria"] == "to_or_cc")
searchCriteria.push("to", "cc");
else if (search["mail"]["criteria"] == "entire_message")
searchCriteria.push("body");
var filters = [];
for (i = 0; i < searchCriteria.length; i++)
filters.push({"searchBy": searchCriteria[i], "searchArgument": "doesContain", "searchInput": searchValue});
urlParams.filters = filters;
}
var sortAttribute = sorting["attribute"];
if (sortAttribute && sortAttribute.length > 0) {
urlParams.set("sort", sorting["attribute"]);
urlParams.set("asc", sorting["ascending"]);
var sortingAttributes = {"sort":sorting["attribute"], "asc":sorting["ascending"], "match":"OR"};
urlParams.sortingAttributes = sortingAttributes;
var sortHeader = $(sorting["attribute"] + "Header");
if (sortHeader) {
@@ -816,18 +863,15 @@ function openMailbox(mailbox, reload) {
var messageList = $("messageListBody").down('TBODY');
var key = mailbox;
if (urlParams.keys().length > 0) {
var p = urlParams.keys().collect(function(key) { return key + "=" + urlParams.get(key); }).join("&");
key += "?" + p;
}
if (reload) {
// Don't change data source, only query UIDs from server and refresh
// the view. Cases that end up here:
// - performed a search
// - clicked on Get Mail button
urlParams.set("no_headers", "1");
Mailer.dataTable.load(urlParams);
urlParams.sortingAttributes.no_headers= "1";
var content = Object.toJSON(urlParams);
Mailer.dataTable.load(content);
Mailer.dataTable.refresh();
}
else {
@@ -843,7 +887,8 @@ function openMailbox(mailbox, reload) {
}
else
// Fetch UIDs and headers from server
dataSource.load(urlParams);
var content = Object.toJSON(urlParams);
dataSource.load(content);
// Cache data source
Mailer.dataSources.set(key, dataSource);
// Update unseen count
@@ -851,8 +896,9 @@ function openMailbox(mailbox, reload) {
}
else {
// Data source is cached, query only UIDs from server
urlParams.set("no_headers", "1");
dataSource.load(urlParams);
urlParams.sortingAttributes.no_headers= "1";
var content = Object.toJSON(urlParams);
dataSource.load(content);
}
// Associate data source with data table and render the view
Mailer.dataTable.setSource(dataSource);
+1 -2
View File
@@ -118,8 +118,7 @@ var SOGoDataTableInterface = {
load: function(urlParams) {
if (!this.dataSource) return;
// log ("DataTable.load() with parameters [" + urlParams.keys().join(' ') + "]");
if (Object.isHash(urlParams) && urlParams.keys().length > 0) this.dataSource.load(urlParams);
else this.dataSource.load(new Hash());
this.dataSource.load(urlParams);
},
visibleRowCount: function() {
+3 -12
View File
@@ -72,22 +72,13 @@ SOGoMailDataSource = Class.create({
// log ("MailDataSource.init() " + this.uids.length + " UIDs, " + this.cache.keys().length + " headers");
},
load: function(urlParams) {
var params;
load: function(content) {
this.loaded = false;
if (urlParams.keys().length > 0) {
params = urlParams.keys().collect(function(key) { return key + "=" + urlParams.get(key); }).join("&");
}
else
params = "";
this.id = this.url + "?" + params;
// log ("MailDataSource.load() " + params);
triggerAjaxRequest(this.url + "/uids",
this._loadCallback.bind(this),
null,
params,
{ "Content-type": "application/x-www-form-urlencoded" });
content,
{ "content-type": "application/json" });
},
_loadCallback: function(http) {
+95
View File
@@ -0,0 +1,95 @@
/*************** Table adjustment *****************/
TABLE#searchMailHeader, TABLE#searchFiltersList, TABLE#searchMailFooter
{ width: 100%; }
TABLE#searchFiltersList, TABLE#searchMailFooter
{
border: 1px solid #909090;
margin-top: 1em;
padding:2px;
border-radius: 3px;
}
TABLE#searchFiltersList
{
display:block;
max-height:100px;
overflow:auto;
width:672px;
}
TABLE#searchMailFooter
{
height:141px;
min-height: 110px;
}
.buttonsCell
{
width:1%;
}
.inputsCell
{
width:45%;
}
.filterRow
{
cellspacing=0;
}
.scrollbar
{
overflow-y:auto;
height:106px;
width:676px;
position:absolute;
}
/*************** Table adjustment : search results *****************/
.resultsRow {
cursor:pointer;
}
/*************** Button adjustment *****************/
#headerButtons
{
width:27%;
}
#searchButton, #cancelButton
{
margin-top:0;
}
.searchByList, .searchArgumentsList, .searchInput
{
width:100%;
}
DIV#optionsButtons
{ float:left; }
.button
{
font-style:normal;
}
#changeHeader
{ width:15px}
DIV.bottomToolbar {
margin:0;
position:relative;
border-radius:5px;
width:40px;
}
/*************** Lists *****************/
.hidden
{ display:none; }
+368
View File
@@ -0,0 +1,368 @@
/* -*- Mode: js2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
var searchParams = {
searchLocation: "",
subfolder: true,
filterMatching: "AND",
filters: []
};
// This variable allowed the user to stop the ongoing search
var stopOngoingSearch = false;
/************ Search mail header ************/
function onSearchClick() {
// This function updates the searchParams
var filterRows = $$(".filterRow");
var searchButton = $("searchButton").down().innerText;
var mailAccountsList = $("mailAccountsList").options;
if (searchButton == _("Search")) {
searchParams.filters = [];
stopOngoingSearch = false;
// Get the mailboxe(s)
for (i = 0; i < mailAccountsList.length ; i++) {
if (mailAccountsList[i].selected) {
searchParams.searchLocation = mailAccountsList[i].innerText;
break;
}
}
for (i = 0; i < filterRows.length; i++){
// Get the information from every filter row before triggering the AJAX call
var filter = {};
var searchByOptions = filterRows[i].down(".searchByList").options;
var searchArgumentsOptions = filterRows[i].down(".searchArgumentsList").options;
var searchInput = filterRows[i].down(".searchInput");
// Get the searchBy
for (j = 0; j < searchByOptions.length ; j++) {
if (searchByOptions[j].selected) {
filter.searchBy = searchByOptions[j].innerText;
break;
}
}
// Get the searchArgument
for (j = 0; j < searchArgumentsOptions.length ; j++) {
if (searchArgumentsOptions[j].selected) {
filter.searchArgument = searchArgumentsOptions[j].innerText;
if (filter.searchArgument == "contains")
filter.searchArgument = "doesContain";
else
filter.searchArgument = "NOT doesContain";
break;
}
}
// Get the input text
filter.searchInput = searchInput.getValue();
// Add the filter inside the searchParams.filters if the input is not empty
if (!filter.searchInput.empty())
searchParams.filters.push(filter);
}
// Send the request only if there is at least one filter
if (searchParams.filters.length > 0) {
$("searchButton").down().innerText = _("Stop");
searchMails();
}
// TODO - give the user a warning or a notice that it needs at least one filter
}
else {
stopOngoingSearch = true;
$("searchButton").down().innerText = _("Search");
}
}
function searchMails() {
// Variables for the subfolders search
var optionsList = $("mailAccountsList").options;
var nbOptions = optionsList.length;
var selectedIndex = optionsList.selectedIndex;
var mailAccountIndex = mailAccounts.indexOf(searchParams.searchLocation);
if (mailAccountIndex != -1) {
var accountNumber = "/" + mailAccountIndex;
var folderName = accountNumber + "/folderINBOX";
var accountUser = userNames[mailAccountIndex];
var folderPath = accountUser;
}
else {
var searchLocation = searchParams.searchLocation.split("/");
var accountUser = searchLocation[0];
var accountNumber = "/" + userNames.indexOf(accountUser);
var position = searchLocation.length;
var folderName = accountNumber + "/folder" + searchLocation[1];
for (i = 2; i < position; i++)
folderName += accountNumber + "/folder" + searchLocation[i];
var folderPath = optionsList[selectedIndex].innerText;
}
var subfolders = [];
if (searchParams.subfolder == true) {
for (i = 0; i < nbOptions; i++) {
if ((optionsList[i].innerText.search(folderPath) != -1) && (i != selectedIndex)) {
var splitArray = optionsList[i].innerText.split("/");
// Remove the user information since it is not required
splitArray.splice(0, 1);
var subfolder = [];
var level = splitArray.length;
for(j = 0; j < level; j++) {
subfolder += "/folder" + splitArray[j];
}
subfolders.push(accountNumber + subfolder);
}
}
}
var urlstr = (ApplicationBaseURL + folderName + "/uids");
var callbackData = {"folderName" : folderName, "subfolders" : subfolders, "newSearch" : true};
var object = {"filters":searchParams.filters, "sortingAttributes":{"match":searchParams.filterMatching}};
var content = Object.toJSON(object);
document.searchMailsAjaxRequest = triggerAjaxRequest(urlstr, searchMailsCallback, callbackData, content, {"content-type": "application/json"});
}
function searchMailsCallback(http) {
if (http.readyState == 4 && http.status == 200 && !stopOngoingSearch) {
var response = http.responseText.evalJSON();
var table = $("searchMailFooter").down("tbody");
// Erase all previous entries before proceeding with the current request
if (http.callbackData.newSearch) {
var oldEntries = table.rows;
var count = oldEntries.length - 1;
for (x = count; x >= 0; x--)
oldEntries[x].remove();
}
// ["To", "Attachment", "Flagged", "Subject", "From", "Unread", "Priority", "Date", "Size", "rowClasses", "labels", "rowID", "uid"]
if (response.headers.length > 1) {
if ($("noSearchResults"))
$("noSearchResults").remove();
for (i = 1; i < response.headers.length; i++) { // Starts at 1 because the position 0 in the array are the headers of the table
var row = table.insertRow(i - 1); // This is the reason why row inserting starts at i - 1
Element.addClassName(row, "resultsRow");
row.writeAttribute("uid", response.headers[i][12]);
row.writeAttribute("folderName", http.callbackData.folderName);
var cell1 = row.insertCell(0);
cell1.innerHTML = response.headers[i][3];
var cell2 = row.insertCell(1);
cell2.innerHTML = response.headers[i][4];
var cell3 = row.insertCell(2);
cell3.innerHTML = response.headers[i][7];
var cell4 = row.insertCell(3);
cell4.innerHTML = response.headers[i][12];
}
}
else if (http.callbackData.newSearch) {
if (!table.down("tr")) {
var row = table.insertRow(0);
var cell = row.insertCell(0);
var element = document.createElement("span");
cell.writeAttribute("id", "noSearchResults");
cell.writeAttribute("colspan", "4");
element.innerText = _("No matches found");
cell.appendChild(element);
}
}
if (http.callbackData.subfolders.length > 0) {
var folderName = http.callbackData.subfolders[0];
var subfolders = http.callbackData.subfolders;
subfolders.splice(0, 1);
var urlstr = (ApplicationBaseURL + folderName + "/uids");
var callbackData = {"folderName" : folderName, "subfolders" : subfolders, "newSearch" : false};
// TODO - need to add these following contents ; asc, no-headers, sort
var object = {"filters":searchParams.filters, "sortingAttributes":{"match":searchParams.filterMatching}};
var content = Object.toJSON(object);
document.searchMailsAjaxRequest = triggerAjaxRequest(urlstr, searchMailsCallback, callbackData, content, {"content-type": "application/json"});
}
else {
$("searchButton").down().innerText = _("Search");
}
}
}
function onCancelClick() {
disposeDialog();
$("searchMailView").remove();
}
function onSearchSubfoldersCheck(event) {
searchParams.subfolder = (event.checked ? true : false);
}
function onMatchFilters(event) {
searchParams.filterMatching = ((event.getAttribute("id") == "matchAllFilters") ? "AND" : "OR");
}
/**** Search mail body ****/
function onAddFilter() {
var table = $("searchFiltersList").down("tbody");
var searchByList = $("searchByList").getElementsByTagName("li");
var stringArgumentsList = $("stringArgumentsList").getElementsByTagName("li");
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
Element.addClassName(row, "filterRow");
var cell1 = row.insertCell(0);
var element1 = document.createElement("select");
Element.addClassName(element1, "searchByList");
element1.writeAttribute("id", "searchByListRow" + rowCount);
for (i = 0; i < searchByList.length; i++) {
var option = document.createElement("option");
option.writeAttribute("value", i);
option.innerHTML = searchByList[i].innerText;
element1.appendChild(option);
}
cell1.appendChild(element1);
var cell2 = row.insertCell(1);
var element2 = document.createElement("select");
Element.addClassName(element2, "searchArgumentsList");
element2.writeAttribute("id", "searchArgumentsListRow" + rowCount);
for (i = 0; i < stringArgumentsList.length; i++) {
var option = document.createElement("option");
option.writeAttribute("value", i);
option.innerHTML = stringArgumentsList[i].innerText;
element2.appendChild(option);
}
cell2.appendChild(element2);
var cell3 = row.insertCell(2);
Element.addClassName(cell3, "inputsCell");
var element3 = document.createElement("input");
Element.addClassName(element3, "searchInput");
element3.writeAttribute("type", "text");
element3.writeAttribute("name", "searchInput");
element3.writeAttribute("value", "");
element3.writeAttribute("id", "searchInputRow" + rowCount);
cell3.appendChild(element3);
var cell4 = row.insertCell(3);
Element.addClassName(cell4, "buttonsCell");
var element4 = document.createElement("a");
var element5 = document.createElement("a");
var buttonsDiv = document.createElement("div");
var spanAddFilter = document.createElement("span");
var imageAddFilter = document.createElement("img");
var spanRemoveFilter = document.createElement("span");
var imageRemoveFilter = document.createElement("img");
Element.addClassName(element4, "addFilterButton");
Element.addClassName(buttonsDiv, "bottomToolbar");
element4.writeAttribute("name", "addFilter");
element4.writeAttribute("id", "addFilterButtonRow" + rowCount);
element4.writeAttribute("onclick", "onAddFilter(this)");
imageAddFilter.writeAttribute("src", "/SOGo.woa/WebServerResources/add-icon.png");
spanAddFilter.appendChild(imageAddFilter);
element4.appendChild(spanAddFilter);
buttonsDiv.appendChild(element4);
Element.addClassName(element5, "removeFilterButton");
element5.writeAttribute("name", "removeFilter");
element5.writeAttribute("id", "removeFilterButtonRow" + rowCount);
element5.writeAttribute("onclick", "onRemoveFilter(this)");
imageRemoveFilter.writeAttribute("src", "/SOGo.woa/WebServerResources/remove-icon.png");
spanRemoveFilter.appendChild(imageRemoveFilter);
element5.appendChild(spanRemoveFilter);
buttonsDiv.appendChild(element5);
cell4.appendChild(buttonsDiv);
}
function onRemoveFilter(event) {
var rows = $("searchFiltersList").down("tbody").getElementsByTagName("tr");
var currentRow = event.up(".filterRow");
if(rows.length > 1)
currentRow.remove();
}
/**** Search mail Footer ****/
function onResultSelectionChange(event) {
var table = $("searchMailFooter").down("tbody");
if (event && (event.target.innerText != _("No matches found"))) {
var node = getTarget(event);
if (node.tagName == "SPAN")
node = node.parentNode;
// Update rows selection
onRowClick(event, node);
}
}
/**** Search mail optionsButtons ****/
function onOpenClick(event) {
// This function is linked with the openButton and the doubleClick on a message
var selectedRow = $("searchMailFooter").down("._selected");
var msguid = selectedRow.getAttribute("uid");
var folderName = selectedRow.getAttribute("folderName");
var url = "/SOGo/so/sogo1/Mail" + folderName + "/" + msguid + "/popupview";
if (selectedRow) {
openMessageWindow(msguid, url);
}
}
function onDeleteClick(event) {
console.debug("deleteButton");
}
function onResizeClick() {
var resizeAttrribute = $("resizeButton").getAttribute("name");
if (resizeAttrribute == "resizeUp") {
$("searchFiltersList").style.display = "none";
$("searchMailFooter").style.height = "300px";
$("resultsTable").style.height = "265px";
$("resizeUp").style.display = "none";
$("resizeDown").style.display = "block";
$("resizeButton").writeAttribute("name", "resizeDown");
}
else {
$("searchFiltersList").style.display = "block";
$("searchMailFooter").style.height = "141px";
$("resultsTable").style.height = "106px";
$("resizeUp").style.display = "block";
$("resizeDown").style.display = "none";
$("resizeButton").writeAttribute("name", "resizeUp");
}
}
/*************** Init ********************/
function initSearchMailView () {
// Add one filterRow
onAddFilter();
// Observers : Event.on(element, eventName[, selector], callback)
$("searchMailFooter").down("tbody").on("mousedown", "tr", onResultSelectionChange);
$("searchMailFooter").down("tbody").on("dblclick", "tr", onOpenClick);
}
+13
View File
@@ -658,6 +658,19 @@ DIV.dialog > DIV
top: 7px;
}
DIV.dialog.searchMail {
position: relative;
margin: 0px;
padding: 0px;
opacity: 1;
width: 700px;
margin: 100px auto;
}
DIV.dialog.searchMail > DIV {
padding: 10px;
}
DIV.dialog.none
{ position: relative;
margin: 0px;
+1 -1
View File
@@ -1998,7 +1998,7 @@ function createDialog(id, title, legend, content, positionClass) {
var newDialog = createElement("div", id, ["dialog", positionClass]);
newDialog.setStyle({"display": "none"});
if (positionClass == "none") {
if (positionClass == "none" || positionClass == "searchMail") {
var bgDiv = $("bgDialogDiv");
if (bgDiv) {
bgDiv.show();