app/assets/javascripts/search/FindPeople.js
Ext.ns('Talho');
Talho.FindPeople = Ext.extend(Ext.util.Observable, {
constructor: function(config){
Talho.FindPeople.superclass.constructor.call(this, config);
this.admin_mode = config.admin_mode;
this.rolesStore = new Ext.data.JsonStore({
url: '/roles.json',
restful: true,
fields: ['name', 'id'],
autoLoad: true
});
this.jurisdictionsStore = new Ext.data.JsonStore({
url: '/jurisdictions.json' + ((this.admin_mode) ? '?admin_mode=1' : ''),
restful: true,
root: 'jurisdictions',
fields: ['name', 'id'],
autoLoad: true
});
this.RESULTS_PAGE_SIZE = 10;
this.resultsStore = new Ext.data.JsonStore({
url: '/search/show_advanced.json' + ((this.admin_mode) ? '?admin_mode=1' : ''),
method: 'POST',
root: 'results',
fields: [ 'user_id', 'display_name','first_name', 'last_name', 'email', 'role_memberships', 'role_requests', 'photo' ],
autoLoad: false,
remoteSort: true,
baseParams: {'limit': this.RESULTS_PAGE_SIZE},
listeners: {
scope: this,
'load': this.handleResults,
'exception': this.handleError
}
});
this.resultsStore.setDefaultSort('last_name', 'asc'); // tell ext what the initial dataset will look like
this.rolesList = new Ext.list.ListView({
store: this.rolesStore,
multiSelect: true,
simpleSelect: true,
columnSort: false,
loadingText: 'Fetching role list...',
emptyText: 'Error: Could not retrieve Roles',
deferEmptyText: true,
hideHeaders: true,
style: { 'background-color': 'white'},
columns: [{dataIndex: 'name', cls: 'rol-list-item' }]
});
this.jurisList = new Ext.list.ListView({
store: this.jurisdictionsStore,
multiSelect: true,
simpleSelect: true,
columnSort: false,
loadingText: 'Fetching jurisdiction list...',
emptyText: 'Error: Could not retrieve Jurisdictions',
deferEmptyText: true,
hideHeaders: true,
style: { 'background-color': 'white'},
columns: [{ dataIndex: 'name', cls: 'jur-list-item'}]
});
this.rolesSelector = new Ext.Panel ({
cls: 'find-people-roles-select',
layout: 'fit',
flex: 1,
width: '100%',
border: false,
tbar: new Ext.Toolbar({items: [
{xtype: 'tbtext', name: 'hdr', html: 'Roles: <i>(none selected)</i>'}, '->',
{xtype: 'button', text: 'Clear All', scope: this, handler: function(){ this.rolesList.clearSelections(); }}
]}),
items: [this.rolesList],
style: { 'padding-bottom': '10px', 'padding-top': '5px'}
});
this.jurisSelector = new Ext.Panel ({
cls: 'find-people-jurisdictions-select',
layout: 'fit',
flex: 1,
width: '100%',
tbar: new Ext.Toolbar({items: [
{xtype: 'tbtext', name: 'hdr', html: 'Jurisdictions: <i>(none selected)</i>'}, '->',
{xtype: 'button', text: 'Clear All', scope: this, handler: function(){ this.jurisList.clearSelections(); }}
]}),
items: [this.jurisList]
});
this.searchSidebar = new Ext.FormPanel({
labelAlign: 'top',
frame: true,
region: 'west',
width: 300,
fill: true,
margins: '5 5 5 5',
layout: 'vbox',
title: 'People Search',
autoScroll: true,
items: [{
layout: 'form',
width: '100%',
items: [
{ fieldLabel: 'Name', name: 'conditions[name]', xtype: 'textfield', anchor: '95%' },
{ fieldLabel: 'Email Address', name: 'conditions[email]', xtype: 'textfield', anchor: '95%' },
{ layout: 'column', items: [
{ columnWidth: .5, layout: 'form',
items: [{ fieldLabel: 'Phone', name: 'conditions[phone]', xtype: 'textfield', anchor: '90%' }]
},
{ columnWidth: .5, layout: 'form',
items: [{ fieldLabel: 'Job Title', name: 'conditions[title]', xtype: 'textfield', anchor: '90%' }]
}]
}]
},
this.rolesSelector,
this.jurisSelector
],
buttonAlign : 'center',
buttons: [
{text: 'Reset', scope: this, handler: this.resetSearchSidebar},
{text: 'Search', scope: this, handler: this.displaySearchResults }
],
keys: [{key: Ext.EventObject.RETURN, shift: false, fn: this.displaySearchResults, scope: this}]
});
this.nameColTemplate = new Ext.XTemplate(
'<div style="float: left; height: 60px; width: 60px;"><img src="{photo}"></div>',
'<div style="float: left; margin-left: 15px; width: 205px;">',
'<span style="white-space:normal; font-weight: bold; font-size: 150%;">{display_name}</span><br/ >',
'<tpl if="(first_name +\' \' + last_name) != display_name">({first_name} {last_name})<br /></tpl>',
'{email}</div>'
);
this.rolesColTemplate = new Ext.XTemplate(
'<tpl for="role_memberships"><p>{.}</p></tpl>',
'<tpl if="role_requests.length > 0"><br>Pending:<br></tpl>',
'<tpl for="role_requests"><p><i>{.}</i></p></tpl>'
);
this.startScreen = new Ext.Panel ({
html: '<div style=" padding: 20px;"><span style="font-size: 200%;">Search</span><br >Use the form at left to get started.</div>'
});
this.noResultsScreen = new Ext.Panel ({
html: '<div style=" padding: 20px;"><span style="font-size: 200%;">No Results</span><br >No users match your search request</div>'
});
this.serverError = new Ext.Panel ({
html: '<div style="padding: 20px;"><span style="font-size: 200%;">Server Error</span><br >There was an error communicating with the server.<br/ >If the problem persists, please contact an administrator.</div>'
});
var admin_mode_buttons = [
{xtype: 'tbspacer', width: 25},
{text: 'Add User', scope: this, handler: function(){
Application.fireEvent('opentab', {title: 'Add User', id: 'add_new_user', initializer: 'Talho.AddUser'});
}},
{text: 'Edit User', name: 'edit_btn', disabled: true, scope: this, handler: function(){
var selected_records = this.searchResults.getSelectionModel().getSelections();
Ext.each(selected_records, function(e,i){ this.openEditUserTab(e) }, this);
}},
{text: 'Delete User', name: 'delete_btn', disabled: true, scope: this, handler: function(){
var selected_records = this.searchResults.getSelectionModel().getSelections();
if (selected_records.length == 0) return;
Ext.Msg.confirm("Confirm User Deletion", "Are you sure you wish to delete " + selected_records.length + " users?",
function(id){
if (id != "yes") return;
var delete_params = new Object;
Ext.each(selected_records, function(record,i){ delete_params["users[user_ids][]"] = record.get('user_id'); });
var json_auth = Ext.apply({}, delete_params);
Ext.Ajax.request({ url: "/admin/users/deactivate.json", method: "POST", params: json_auth,
success: function(response){this.ajax_success_cb(response)},
failure: function(response){this.ajax_err_cb(response)}, scope: this });
}, this);
}}
];
this.searchResults = new Ext.grid.GridPanel({
cls: 'people-results',
layout: 'hbox',
store: this.resultsStore,
colModel: new Ext.grid.ColumnModel({
columns: [
{ id: 'user', dataIndex: 'last_name', header: 'Search Results', sortable: true, width: 300, xtype: 'templatecolumn', tpl: this.nameColTemplate },
{ id: 'roles', dataIndex: 'role_memberships', header: 'Roles', sortable: false, width: 350, xtype: 'templatecolumn', tpl: this.rolesColTemplate }
]
}),
selModel: new Ext.grid.RowSelectionModel({
listeners: {scope:this, 'selectionchange': this.set_edit_delete_state}
}),
listeners: {
scope: this,
'cellclick': function(grid, row, column, e){
if (this.admin_mode) return true;
var record = grid.getStore().getAt(row); // Get the Record
this.openUserProfileTab(record);
},
'celldblclick': function(grid, row, column, e){
if (!this.admin_mode) return true;
var record = grid.getStore().getAt(row); // Get the Record
this.openEditUserTab(record);
}
},
tbar: new Ext.PagingToolbar({
pageSize: this.RESULTS_PAGE_SIZE,
store: this.resultsStore,
displayInfo: true,
displayMsg: 'Displaying results {0} - {1} of {2}',
emptyMsg: "No results",
items: [
(this.admin_mode) ? admin_mode_buttons : []
]
})
});
this.searchResultsContainer = new Ext.Panel({
region: 'center',
layout: 'card',
activeItem: 0,
frame: false,
border: true,
bodyBorder: false,
margins: '5 5 5 0',
padding: '0',
items: [
this.startScreen,
this.searchResults,
this.noResultsScreen,
this.serverError
],
listeners: {
scope: this,
'afterrender': function(cmp){ this.searchingLoadMask = new Ext.LoadMask(cmp.getEl(), { msg:"Searching...", store: this.resultsStore }); }
}
});
this.primary_panel = new Ext.Panel({
layout:'border',
itemId: config.id,
closable: true,
items: [
this.searchSidebar,
this.searchResultsContainer
],
title: config.title
});
this.getPanel = function(){
return this.primary_panel;
};
this.rolesList.on('selectionchange', function(view, nodes){
var l = nodes.length;
if (l == 0) { l = 'none'}
var hdrText = 'Roles: <i>('+l+' selected)</i>';
this.rolesSelector.getTopToolbar().find('name', 'hdr')[0].setText(hdrText);
}, this );
this.jurisList.on('selectionchange', function(view, nodes){
var l = nodes.length;
if (l == 0) { l = 'none'}
var hdrText = 'Jurisdictions: <i>('+l+' selected)</i>';
this.jurisSelector.getTopToolbar().find('name', 'hdr')[0].setText(hdrText);
}, this );
if (this.admin_mode)
this.primary_panel.on('afterrender', function(){ this.searchResults.store.load(); }, this);
},
resetSearchSidebar: function(btn,evt){
this.searchSidebar.getForm().reset();
this.rolesList.clearSelections();
this.jurisList.clearSelections();
},
handleResults: function(store){
if (store.getCount() < 1){
this.searchResultsContainer.layout.setActiveItem(2); // no_results
} else {
this.searchResultsContainer.layout.setActiveItem(1); // show_results
}
},
handleError: function(proxy, type, action, options, response, arg){
this.show_err_message(Ext.decode(response.responseText));
this.searchResultsContainer.layout.setActiveItem(3); // search_error
},
applyFilters: function(params){ //add selected role and juri IDs, because they are not part of the form
var roleIds = [];
var jurisIds = [];
var selectedRoles = this.rolesList.getSelectedRecords();
var selectedJurisdictions = this.jurisList.getSelectedRecords();
for (var r = 0; r < this.rolesList.getSelectionCount(); r++ ){
roleIds[r] = selectedRoles[r].json.id;
}
for (var j = 0; j < this.jurisList.getSelectionCount(); j++ ){
jurisIds[j] = selectedJurisdictions[j].json.id;
}
params['with[jurisdiction_ids][]'] = jurisIds;
params['with[role_ids][]'] = roleIds;
return true;
},
displaySearchResults: function(form, action) {
var searchData = this.searchSidebar.getForm().getValues();
this.applyFilters(searchData);
for (var derp in searchData ){
this.searchResults.store.setBaseParam( derp, searchData[derp] );
}
this.searchResults.store.load();
},
openUserProfileTab: function(record){
var user_id = record.get('user_id');
Application.fireEvent('opentab',
{title: 'Profile: ' + record.get('display_name'), user_id: user_id, id: 'user_profile_for_' + user_id, initializer: 'Talho.ShowProfile'});
},
openEditUserTab: function(record){
var user_id = record.get('user_id');
var name = record.get('first_name') + ' ' + record.get('last_name');
var url = '/users/' + user_id + '/profile';
Application.fireEvent('opentab',
{title: 'Edit User: ' + name, url: url, user_id: user_id, id: 'edit_user_for_' + user_id, initializer: 'Talho.EditProfile'});
},
set_edit_delete_state: function(selModel){
if (!this.admin_mode) return;
var selected_records = selModel.getSelections();
var tbar = this.searchResults.getTopToolbar();
tbar.find("name", "edit_btn")[0].setDisabled(selected_records.length == 0);
tbar.find("name", "delete_btn")[0].setDisabled(selected_records.length == 0);
},
ajax_success_cb: function(response, opts) {
var json = Ext.decode(response.responseText);
if (json.delete_result) {
var selected_records = this.searchResults.getSelectionModel().getSelections();
this.resultsStore.remove(selected_records);
} else {
this.show_err_message(json);
}
},
ajax_err_cb: function(response, opts) {
var msg = '<b>Status: ' + response.status + ' => ' + response.statusText + '</b><br><br>' +
'<div style="height:400px;overflow:scroll;">' + response.responseText + '<\div>';
Ext.Msg.show({title: 'Error', msg: msg, minWidth: 900, maxWidth: 900, buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR});
},
show_err_message: function(json) {
var w = 300;
var msg = '<b>Server Error:</b> ' + json.error + '<br>';
if (json.exception != null) {
w = 900;
msg += '<b>Exception:</b> ' + json.exception + '<br><br>';
msg += '<div style="height:400px;overflow:scroll;">';
for (var i = 0; i < json.backtrace.length; i++)
msg += ' ' + json.backtrace[i] + '<br>';
msg += '<\div>';
}
Ext.Msg.show({title: 'Error', msg: msg, minWidth: w, maxWidth: w, buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR});
}
});
/**
* Initializer for the FindPeople object. Returns a panel
*/
Talho.FindPeople.initialize = function(config){
var find_people_panel = new Talho.FindPeople(config);
return find_people_panel.getPanel();
};
Talho.ScriptManager.reg('Talho.FindPeople', Talho.FindPeople, Talho.FindPeople.initialize);