Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4269aa1

Browse files
Big update: added search/recent for canonical events, canonical event search, removed some of the buttons article and event level description, and cleaned up some function wrappers for tab switching
1 parent 616688b commit 4269aa1

File tree

9 files changed

+194
-96
lines changed

9 files changed

+194
-96
lines changed

‎models.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from sqlalchemy import Column, Date, DateTime, Integer, String, Unicode, ForeignKey, UniqueConstraint, Text, UnicodeText
22
from sqlalchemy.orm import relationship, backref
33
from flask_login import UserMixin
4+
from sqlalchemy.sql.expression import desc
45
from database import Base
56
import datetime as dt
67
from pytz import timezone
@@ -34,16 +35,17 @@ class CanonicalEvent(Base):
3435
id = Column(Integer, primary_key=True)
3536
coder_id = Column(Integer, ForeignKey('user.id'), nullable = False)
3637
key = Column(Text, nullable = False)
38+
description = Column(UnicodeText, nullable = False)
3739
notes = Column(UnicodeText)
3840
last_updated = Column(DateTime)
3941

4042
UniqueConstraint('key', name = 'unique1')
4143

42-
def __init__(self, coder_id, key, notes=None, status = 'In Progress'):
44+
def __init__(self, coder_id, key, description, notes = None):
4345
self.coder_id = coder_id
4446
self.key = key
47+
self.description = description,
4548
self.notes = notes
46-
self.status = status
4749
self.last_updated = dt.datetime.now(tz = central).replace(tzinfo = None)
4850

4951
def __repr__(self):

‎mpeds_coder.py‎

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -574,23 +574,22 @@ def adj():
574574
if current_user.authlevel < 2:
575575
return redirect(url_for('index'))
576576

577-
## Get five recent events
577+
## Get most recent candidate events.
578578
recent_events = [x[0] for x in db_session.query(EventMetadata, RecentEvent).\
579579
join(EventMetadata, EventMetadata.event_id == RecentEvent.event_id).\
580580
order_by(desc(RecentEvent.last_accessed)).limit(5).all()]
581581

582-
# search_canonical_events = db_session.query(CanonicalEvent, CanonicalEventLink, CodeEventCreator).\
583-
# join(CanonicalEventLink, CanonicalEvent.id == CanonicalEventLink.canonical_id).\
584-
# join(CodeEventCreator, CanonicalEventLink.cec_id == CodeEventCreator.id).\
585-
# filter(CanonicalEvent.key == canonical_event_key).all()
582+
## Get most recent canonical events.
583+
## TODO: Add in user by name.
584+
recent_canonical_events = db_session.query(CanonicalEvent).\
585+
join(RecentCanonicalEvent, CanonicalEvent.id == RecentCanonicalEvent.canonical_id).\
586+
order_by(desc(RecentCanonicalEvent.last_accessed)).limit(5).all()
586587

587588
## TODO: Base this off EventMetadata for now. Eventually, we want to get rid of this.
588589
filter_fields = EventMetadata.__table__.columns.keys()
589590
filter_fields.remove('id')
590591
filter_fields.append('flag')
591592

592-
## TODO: Do some checks in the template which don't force us to enter in empty variables
593-
## which will be initialized by load_adj_grid
594593
return render_template("adj.html",
595594
search_events = [],
596595
filter_fields = filter_fields,
@@ -599,7 +598,7 @@ def adj():
599598
links = [],
600599
flags = [],
601600
recent_events = recent_events,
602-
# recent_canonical_events = recent_canonical_events,
601+
recent_canonical_events = recent_canonical_events,
603602
canonical_event = None)
604603

605604

@@ -747,13 +746,10 @@ def do_search():
747746
## get all flags for these events
748747
flags = _load_event_flags([x.event_id for x in search_events])
749748

750-
## TODO: Eventually need to load current candidate events.
751-
## Will probably end up doing this in JavaScript with the button initializers.
752749
response = make_response(
753750
render_template('adj-search-block.html',
754751
events = search_events,
755-
flags = flags,
756-
cand_events = {})
752+
flags = flags)
757753
)
758754

759755
url_params = {k: v for k, v in request.form.iteritems()}
@@ -764,6 +760,28 @@ def do_search():
764760
return response
765761

766762

763+
@app.route('/search_canonical', methods = ['POST'])
764+
@login_required
765+
def search_canonical():
766+
"""Loads a set of canonical events which meet search criteria."""
767+
canonical_search_term = request.form['canonical_search_term']
768+
769+
if canonical_search_term == '':
770+
return make_response("Please enter a search term.", 400)
771+
772+
## Construct search in all available fields
773+
filter_expr = or_(
774+
CanonicalEvent.key.like(u'%{}%'.format(canonical_search_term)),
775+
CanonicalEvent.description.like(u'%{}%'.format(canonical_search_term)),
776+
CanonicalEvent.notes.like(u'%{}%'.format(canonical_search_term))
777+
)
778+
779+
## search for the canonical event in key and notes
780+
rs = db_session.query(CanonicalEvent).filter(filter_expr).all()
781+
782+
return render_template('adj-canonical-search-block.html', events = rs)
783+
784+
767785
@app.route('/adj_search/<function>', methods = ['POST'])
768786
@login_required
769787
def adj_search(function):

‎static/adj.js‎

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11

2-
var MAX_CAND_EVENTS = 4;
3-
42
/**
53
*
64
* @param {*} e - Event
@@ -36,17 +34,6 @@ var changeTab = function(e, level = "") {
3634
return false;
3735
}
3836

39-
/**
40-
* Wrapper to change subtabs
41-
* @param {*} e - Event
42-
* @returns false
43-
* */
44-
var changeSubTab = function(e) {
45-
changeTab(e, "sub");
46-
return false;
47-
}
48-
49-
5037
/**
5138
* Gets the current candidate events in the grid
5239
* @param {str} to_exclude - candidates to exclude
@@ -177,6 +164,7 @@ var removeCanonical = function () {
177164
var new_url = 'adj?' + curr_search_params.toString();
178165
window.history.pushState({path: new_url}, '', new_url);
179166

167+
markGridEvents();
180168
initializeSearchListeners();
181169

182170
// get rid of loading flash
@@ -288,18 +276,43 @@ var makeError = function(msg) {
288276
return false;
289277
}
290278

279+
/**
280+
* Marks the given candidate events as in the grid.
281+
* */
282+
var markGridEvents = function() {
283+
let search_params = new URLSearchParams(window.location.search);
284+
var cand_events = search_params.get('cand_events').split(',');
285+
286+
// Mark all events as not in the grid.
287+
$('.event-desc').each(function() {
288+
$(this).find('.cande-isactive').hide();
289+
$(this).find('.cande-makeactive').show();
290+
});
291+
292+
// Mark events which are in the grid as active.
293+
for (var i = 0; i < cand_events.length; i++) {
294+
let event_desc = $('.event-desc[data-event="' + cand_events[i] + '"]');
295+
event_desc.find('.cande-isactive').show();
296+
event_desc.find('.cande-makeactive').hide();
297+
}
298+
}
299+
291300
/**
292301
* Initialize listeners for search pane.
293302
* Will need to perform this on every reload of the search pane.
294303
*
295304
*/
296305
var initializeSearchListeners = function() {
306+
var MAX_CAND_EVENTS = 4;
307+
297308
// listeners for current search results
298309
$('.cande-makeactive').click(function(e) {
310+
e.preventDefault();
311+
299312
var event_desc = $(e.target).closest('.event-desc');
300313
var event_id = event_desc.attr('data-event');
301314
let search_params = new URLSearchParams(window.location.search);
302-
var cand_events = search_params.get('cand_events').split(',');
315+
var cand_events = search_params.get('cand_events').split(',');
303316

304317
// remove last event from the list if full
305318
if (cand_events.length == MAX_CAND_EVENTS) {
@@ -316,10 +329,12 @@ var initializeSearchListeners = function() {
316329
canonical_event_key = search_params.get('canonical_event_key'),
317330
cand_events_str = cand_events.join(',')
318331
);
332+
333+
// update all grid events
334+
markGridEvents();
319335

320-
// hide link to add to grid, show cande-isactive
321-
$(e.target).hide();
322-
event_desc.find('.cande-isactive').show();
336+
// $(e.target).hide();
337+
// event_desc.find('.cande-isactive').show();
323338

324339
return true;
325340
});
@@ -499,6 +514,8 @@ var initializeGridListeners = function() {
499514
canonical_event_key = canonical_event_key,
500515
cand_event_str = getCandidates(to_exclude)
501516
);
517+
518+
markGridEvents();
502519
});
503520

504521
// Remove the link to this canonical event
@@ -573,8 +590,12 @@ $(function () {
573590
});
574591

575592
// Add listener to subtab links
576-
$(".subtablinks").each(function(){
577-
$(this).click(changeSubTab);
593+
$(".cand-subtablinks").each(function(){
594+
$(this).click(function(e) { changeTab(e, 'cand-sub'); });
595+
});
596+
597+
$(".canonical-subtablinks").each(function(){
598+
$(this).click(function(e) { changeTab(e, 'canonical-sub'); });
578599
});
579600

580601
// hide search panel
@@ -643,6 +664,38 @@ $(function () {
643664
});
644665
});
645666

667+
// Listener for canonical event search
668+
$('#canonical-search-button').click(function(e) {
669+
e.preventDefault();
670+
// Get the canonical event key from the search box
671+
var canonical_search_term = $('#canonical-search-term').val();
672+
673+
// Get the candidates from the database
674+
var req = $.ajax({
675+
url: $SCRIPT_ROOT + '/search_canonical',
676+
type: "POST",
677+
data: {
678+
canonical_search_term: canonical_search_term
679+
},
680+
beforeSend: function () {
681+
$('.flash').removeClass('alert-danger');
682+
$('.flash').addClass('alert-info');
683+
$('.flash').text("Loading...");
684+
$('.flash').show();
685+
}
686+
})
687+
.done(function() {
688+
// Update the canonical events in the search list
689+
$('#canonical-search-block').html(req.responseText);
690+
691+
// get rid of loading flash
692+
$('.flash').hide();
693+
$('.flash').removeClass('alert-info');
694+
return true;
695+
})
696+
.fail(function() { return makeError(req.responseText); });
697+
});
698+
646699
// initialize the grid and search
647700
let search_params = new URLSearchParams(window.location.search);
648701
var repeated_fields = [

‎static/style.css‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,11 @@ footer {
376376
/*
377377
Adjudication variables
378378
*/
379-
.adj-variable-group, .cand-event-group {
379+
.adj-variable-group, .event-group {
380380
padding: 6px 0;
381381
}
382382

383-
.cand-event-group {
383+
.event-group {
384384
max-height: 640px;
385385
overflow-y: scroll;
386386
}
@@ -416,7 +416,7 @@ span.adj-variable:hover {
416416
background-color: #CCC;
417417
}
418418

419-
div.cand-event-group div.event-desc {
419+
div.event-group div.event-desc {
420420
height: 150px;
421421
width: auto;
422422
overflow-y: scroll;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<div class="event-group" id="canonical-search-block">
2+
{% for e in events %}
3+
<div class="event-desc" id="canonical-event_{{ e.id }}" data-event="{{ e.id }}">
4+
<div class="row">
5+
<div class="col-sm-9">
6+
<b>key:</b> {{ e.key }}</br>
7+
<b>event_id:</b> {{ e.id }}<br/>
8+
<b>coder:</b> {{ e.coder_id }} <br/>
9+
<b>last updated:</b> {{ e.last_updated }}
10+
</div>
11+
<div class="col-sm-3">
12+
<a href="#" class="canonical-makeactive">
13+
<b>Add to grid <span class="glyphicon glyphicon-export"></span></b>
14+
</a>
15+
<b class="canonical-isactive text-muted" style="display:none;">In the grid</b>
16+
</div>
17+
</div>
18+
<div class="row">
19+
<div class="col-sm-12">
20+
<b>desc:</b> {{ e.description | safe }}<br/>
21+
<b>notes:</b> {{ e.notes | safe }}
22+
</div>
23+
</div>
24+
</div>
25+
{% endfor %}
26+
</div>

‎templates/adj-grid.html‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% set var_adds = ['article-desc', 'desc', 'start-date', 'end-date', 'location'] -%}
1+
{% set var_adds = ['start-date', 'end-date', 'location'] -%}
22
{% if canonical_event is none and (cand_events is none or cand_events.keys()|length == 0) %}
33
<p class="info-block bg-info text-info">
44
Get started by selected or adding events.
@@ -94,9 +94,15 @@
9494
{% for value, cec_id, timestamp in cand_events[event_id][var] %}
9595
<div class="expanded-event-variable" data-var="{{ var }}">
9696
<div class="sticky-top data-buttons">
97-
<a class="glyphicon glyphicon-plus add-val"
98-
title="Add to canonical event"
99-
data-key="{{ cec_id }}"></a>
97+
{% if var in ['article-desc', 'desc'] %}
98+
{% if var == 'desc' %}
99+
<a class="glyphicon glyphicon-duplicate" href="#" title="Copy to clipboard"></a>
100+
{% endif %}
101+
{% else %}
102+
<a class="glyphicon glyphicon-plus add-val"
103+
title="Add to canonical event"
104+
data-key="{{ cec_id }}"></a>
105+
{% endif %}
100106
<a class="glyphicon glyphicon-info-sign"
101107
title="Edited on {{ timestamp }}"></a>
102108
</div>

‎templates/adj-search-block.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="cand-event-group">
1+
<div class="event-group">
22
{% for e in events %}
33
<div class="event-desc" id="cand-event_{{ e.event_id }}" data-event="{{ e.event_id }}">
44
<div class="row">

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /