contacts: search and details (#8190)

This commit is contained in:
Frédéric Péters 2015-09-24 12:28:56 +02:00
parent 52a09b6d1a
commit bda5855d0e
8 changed files with 132 additions and 15 deletions

View File

@ -0,0 +1,14 @@
{% load i18n %}
<div class="contact">
<input type="hidden" id="current-selected-user" name="current-selected-user" value="{{user_id}}"/>
<h3>{{user_display_name}}</h3>
{% if forms %}
<p>{% trans "Forms" %}</p>
<ul>
{% for form in forms %}
<li>{{form.title}}, {{form.form_receipt_date}}</li>
{% endfor %}
</ul>
{% endif %}
</div>

View File

@ -1,9 +1,16 @@
{% load i18n %}
<div data-page-fragment-url="{% url 'contacts-zone' %}/">
<div data-contact-fragment-url="{% url 'contacts-zone' %}/">
<div class="search">
<input type="text" autocomplete="off" placeholder="{% trans 'Name, phone, etc.' %}" data-autocomplete-json="{% url 'contacts-search-json' %}" name="q"/>
<ul class="result">
</ul>
</div>
<button>{% trans 'Create new contact' %}</button>
<button id="create-new-contact">+</button>
<div class="contact">
</div>
<div class="back-to-empty">
<a href="#" class="reset">{% trans 'Back to search' %}</a>
</div>
</div>

View File

@ -14,11 +14,16 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import json
from django import template
from django.http import HttpResponse
from django.template import RequestContext
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView
from welco.utils import get_wcs_data
class HomeZone(object):
def __init__(self, request):
self.request = request
@ -41,7 +46,30 @@ zone = csrf_exempt(ContactsZone.as_view())
def search_json(request):
query = request.GET.get('q')
result = []
if query:
result = get_wcs_data('api/users/', {'q': query, 'limit': 10})
if result.get('err') != 0:
raise Exception('error %r' % result)
for user in result.get('data'):
user['title'] = user['user_display_name']
user['slug'] = 'user-%s' % user['user_id']
else:
result = {'data': []}
response = HttpResponse(content_type='application/json')
json.dump({'data': result}, response, indent=2)
json.dump(result, response, indent=2)
return response
class ContactDetailFragmentView(TemplateView):
template_name = 'contacts/contact_detail_fragment.html'
def get_context_data(self, **kwargs):
context = super(ContactDetailFragmentView, self).get_context_data(**kwargs)
user_id = self.kwargs.get('slug').split('-')[-1]
user_details = get_wcs_data('api/users/%s/' % user_id)
context.update(user_details)
context['forms'] = get_wcs_data('api/users/%s/forms' % user_id)
context['user_id'] = user_id
return context
contact_detail_fragment = ContactDetailFragmentView.as_view()

View File

@ -161,15 +161,26 @@ form#kb-search {
margin: 0 1ex;
}
.kb ul.result {
ul.result {
margin: 2ex 0 0 0;
padding: 0;
list-style: circle;
list-style: none;
}
.kb ul.result li {
margin-left: 2em;
margin-bottom: 1ex;
ul.result li {
margin: -1px 1em 0 2px;
border: 1px solid #ccc;
}
ul.result li a {
display: block;
padding: 1ex;
text-decoration: none;
border-bottom: 0;
}
ul.result li a:hover {
background: #eee;
}
.kb div.page {
@ -200,11 +211,13 @@ form#kb-search {
float: left;
}
.contacts .back-to-empty,
.kb .back-to-empty,
.kb.top.has-page-displayed .back-to-empty {
display: none;
}
.contacts.has-contact-displayed .back-to-empty,
.kb.has-page-displayed .back-to-empty {
display: block;
padding: 1ex;
@ -275,3 +288,17 @@ div.qualif-source input#id_post_date {
div.buttons {
margin-top: 1em;
}
button#create-new-contact {
position: absolute;
top: 0;
right: 1em;
}
.contacts.has-contact-displayed .contact {
margin: 1ex;
}
.contacts.has-contact-displayed .search {
display: none;
}

View File

@ -89,10 +89,10 @@ $(function() {
$('.qualif .add-formdef-reference').show();
});
$('.kb').delegate('a.reset', 'click', function() {
$('.kb, .contacts').delegate('a.reset', 'click', function() {
var source_type = $('div.source div[data-source-type]').data('source-type');
var source_pk = $('div.source .active[data-source-pk]').data('source-pk');
$('.cell.kb[data-zone-url]').each(function(idx, zone) {
$(this).parents('.cell').each(function(idx, zone) {
$.ajax({url: $(zone).data('zone-url'),
data: {source_type: source_type,
source_pk: source_pk},
@ -101,6 +101,7 @@ $(function() {
success: function(data) {
$(zone).find('> div').replaceWith(data);
$(zone).find('select').select2();
$(zone).removeClass('has-contact-displayed');
$(zone).removeClass('has-page-displayed');
},
error: function(error) { console.log(':(', error); }
@ -108,13 +109,14 @@ $(function() {
});
});
$('.kb').delegate('input', 'keyup', function() {
$('.kb, .contacts').delegate('input', 'keyup', function() {
var q = $(this).val();
var search_result_ul = $(this).parent().find('ul.result');
search_result_ul.empty();
$.getJSON($(this).data('autocomplete-json'),
{'q': q},
function (response) {
search_result_ul.empty();
$(response.data).each(function(idx, elem) {
$('<li><a href="#" data-page-slug="' + elem.slug + '">' + elem.title + '</a>' + '</li>'
).appendTo(search_result_ul);
@ -138,6 +140,20 @@ $(function() {
return false;
});
$('.contacts').delegate('ul.result a', 'click', function() {
var user_slug = $(this).data('page-slug');
var fragment_url = $(this).parents('[data-contact-fragment-url]').data('contact-fragment-url') + user_slug + '/';
$.ajax({url: fragment_url,
method: 'GET',
dataType: 'html',
success: function(data) {
$('.contacts .contact').replaceWith(data);
$('.contacts').addClass('has-contact-displayed');
},
error: function(error) { console.log(':(', error); }
});
return false;
});
$('#pdf-viewer').on('load', function() {
$('.mails ul li[data-pdf-href]:first-child').trigger('click');

View File

@ -12,8 +12,8 @@
<h2>{% trans 'Knowledge Database' %}</h2>
{{ kb.render }}
</div>
<div class="cell contacts">
<h2>{% trans 'Contacts' %}</h2>
<div class="cell contacts" data-zone-url="{% url 'contacts-zone' %}">
<h2>{% trans 'Contact' %}</h2>
{{ contacts.render }}
</div>
<div class="cell qualif" data-zone-url="{% url 'qualif-zone' %}">

View File

@ -39,6 +39,8 @@ urlpatterns = patterns('',
url(r'^ajax/contacts$', 'welco.contacts.views.zone', name='contacts-zone'),
url(r'^contacts/search/json/$', 'welco.contacts.views.search_json', name='contacts-search-json'),
url(r'^ajax/contacts/(?P<slug>[\w-]+)/$',
'welco.contacts.views.contact_detail_fragment', name='contact-page-fragment'),
url(r'^admin/', include(admin.site.urls)),
url(r'^logout/$', 'welco.views.logout', name='auth_logout'),

View File

@ -119,7 +119,6 @@ def push_wcs_formdata(request, formdef_reference, context=None):
if context:
data['context'] = context
orig = urlparse.urlparse(request.build_absolute_uri('/')).netloc.split(':')[0]
url += 'orig=%s' % wcs_site.get('orig')
if request.session.get('mellon_session'):
mellon = request.session['mellon_session']
@ -133,3 +132,27 @@ def push_wcs_formdata(request, formdef_reference, context=None):
if response.json().get('err') != 0:
raise Exception('error %r' % response.content)
return response.json()['data']['id']
def get_wcs_data(endpoint, params=None):
wcs_site = get_wcs_services().values()[0]
wcs_site_url = wcs_site['url']
if not wcs_site_url.endswith('/'):
wcs_site_url += '/'
url = wcs_site_url + endpoint
if params:
params = params.copy()
for param, value in params.items():
if isinstance(value, unicode):
params[param] = value.encode('utf-8')
else:
params = {}
params['orig'] = wcs_site.get('orig')
if params:
url += '?' + urllib.urlencode(params.items())
url = sign_url(url, wcs_site.get('secret'))
response = requests.get(url)
response.raise_for_status()
return response.json()