Skip to content

Commit 163b39a

Browse files
authored
Merge pull request #143 from mbillow/new-year
New Year Flow
2 parents 894cb9e + 699958c commit 163b39a

File tree

8 files changed

+250
-4
lines changed

8 files changed

+250
-4
lines changed

conditional/blueprints/housing.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from conditional.util.ldap import ldap_get_member
1212
from conditional.util.ldap import ldap_get_roomnumber
1313
from conditional.util.ldap import ldap_get_current_students
14+
from conditional.util.ldap import ldap_set_active
1415

1516
from conditional.util.flask import render_template
1617

@@ -118,6 +119,8 @@ def change_room_numbers(rmnumber):
118119
account = ldap_get_member(occupant)
119120
account.roomNumber = rmnumber
120121
log.info('api', action='%s assigned to room %s' % (occupant, rmnumber))
122+
ldap_set_active(account)
123+
log.info('api', action='%s marked as active because of room assignment' % occupant)
121124
# Delete any old occupants that are no longer in room.
122125
for old_occupant in [account for account in current_students
123126
if ldap_get_roomnumber(account) == str(rmnumber)
@@ -138,3 +141,24 @@ def get_occupants(rmnumber):
138141
occupants = [account.uid for account in current_students
139142
if ldap_get_roomnumber(account) == str(rmnumber)]
140143
return jsonify({"room": rmnumber, "occupants": occupants}), 200
144+
145+
146+
@housing_bp.route('/housing', methods=['DELETE'])
147+
def clear_all_rooms():
148+
log = logger.new(user_name=request.headers.get("x-webauth-user"),
149+
request_id=str(uuid.uuid4()))
150+
log.info('api', action='clear all room numbers')
151+
152+
username = request.headers.get('x-webauth-user')
153+
account = ldap_get_member(username)
154+
155+
if not ldap_is_eval_director(account):
156+
return "must be eval director", 403
157+
# Get list of current students.
158+
current_students = ldap_get_current_students()
159+
160+
# Find the current occupants and clear them.
161+
for occupant in current_students:
162+
log.info('api', action='remove room %s from %s' % (occupant.roomNumber, occupant.uid))
163+
occupant.roomNumber = None
164+
return jsonify({"success": True}), 200

conditional/blueprints/member_management.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@
3333
from conditional.util.ldap import ldap_set_active
3434
from conditional.util.ldap import ldap_set_inactive
3535
from conditional.util.ldap import ldap_set_housingpoints
36+
from conditional.util.ldap import ldap_set_current_student
37+
from conditional.util.ldap import ldap_set_non_current_student
3638
from conditional.util.ldap import ldap_get_active_members
3739
from conditional.util.ldap import ldap_get_member
40+
from conditional.util.ldap import ldap_get_current_students
3841
from conditional.util.ldap import _ldap_add_member_to_group as ldap_add_member_to_group
3942
from conditional.util.ldap import _ldap_remove_member_from_group as ldap_remove_member_from_group
4043
from conditional.util.ldap import _ldap_is_member_of_group as ldap_is_member_of_group
@@ -549,7 +552,7 @@ def introductory_project_submit():
549552
def get_member(uid):
550553
log = logger.new(user_name=request.headers.get("x-webauth-user"),
551554
request_id=str(uuid.uuid4()))
552-
log.info('api', action='submit introductory project results')
555+
log.info('api', action="get {}'s information".format(uid))
553556

554557
username = request.headers.get('x-webauth-user')
555558
account = ldap_get_member(username)
@@ -565,3 +568,66 @@ def get_member(uid):
565568
}
566569

567570
return jsonify(account_dict), 200
571+
572+
@member_management_bp.route('/manage/active', methods=['DELETE'])
573+
def clear_active_members():
574+
log = logger.new(user_name=request.headers.get("x-webauth-user"),
575+
request_id=str(uuid.uuid4()))
576+
log.info('api', action='clear active group')
577+
578+
username = request.headers.get('x-webauth-user')
579+
account = ldap_get_member(username)
580+
581+
if not ldap_is_eval_director(account):
582+
return "must be eval director", 403
583+
# Get the active group.
584+
members = ldap_get_active_members()
585+
586+
# Clear the active group.
587+
for account in members:
588+
log.info('api', action='remove %s from active status' % account.uid)
589+
ldap_set_inactive(account)
590+
return jsonify({"success": True}), 200
591+
592+
593+
@member_management_bp.route('/manage/current/<uid>', methods=['POST', 'DELETE'])
594+
def remove_current_student(uid):
595+
log = logger.new(user_name=request.headers.get("x-webauth-user"),
596+
request_id=str(uuid.uuid4()))
597+
598+
599+
username = request.headers.get('x-webauth-user')
600+
account = ldap_get_member(username)
601+
602+
if not ldap_is_eval_director(account):
603+
return "must be eval director", 403
604+
605+
member = ldap_get_member(uid)
606+
if request.method == 'DELETE':
607+
log.info('api', action='remove {} from current_student'.format(uid))
608+
ldap_set_non_current_student(member)
609+
elif request.method == 'POST':
610+
log.info('api', action='add {} to current_student'.format(uid))
611+
ldap_set_current_student(member)
612+
return jsonify({"success": True}), 200
613+
614+
615+
@member_management_bp.route('/manage/new', methods=['GET'])
616+
def new_year():
617+
log = logger.new(user_name=request.headers.get("x-webauth-user"),
618+
request_id=str(uuid.uuid4()))
619+
log.info('api', action='show new year page')
620+
621+
username = request.headers.get('x-webauth-user')
622+
account = ldap_get_member(username)
623+
624+
if not ldap_is_eval_director(account):
625+
return "must be eval director", 403
626+
627+
current_students = ldap_get_current_students()
628+
629+
630+
return render_template(request,
631+
'new_year.html',
632+
username=username,
633+
current_students=current_students)

conditional/templates/member_management.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ <h3 class="panel-title">Administration</h3>
2727
<div class="stat-title">Intro Accounts</div>
2828
</div>
2929
{% if is_eval_director %}
30-
<div class="col-xs-12 col-sm-4 align-center">
30+
<div class="col-xs-6 col-sm-2 align-center">
3131
<div class="material-switch">
3232
<div class="switch-label">Site Lockdown</div>
3333
<input type="checkbox" id="siteLockdownSwitch" name="siteLockdownSwitch" data-module="siteSettings" data-setting="siteLockdown"{% if site_lockdown %} checked{% endif %}>
3434
<label for="siteLockdownSwitch" class="label-primary"></label>
3535
</div>
3636
</div>
37+
<div class="col-xs-6 col-sm-2 align-center">
38+
<a href="/manage/new" class="btn btn-danger btn-sm btn-new-year"><span class="glyphicon glyphicon-repeat"></span> New Year</a>
39+
</div>
3740
{% endif %}
3841
</div>
3942
</div>

conditional/templates/new_year.html

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{% extends "nav.html" %}
2+
{% block title %}
3+
New Year Guide
4+
{% endblock %}
5+
{% block body %}
6+
<div class="container main">
7+
<div id="new-welcome">
8+
<h3 class="page-title">Welcome!</h3>
9+
<p>Is it that time of year already? Before we get started, please <strong>be careful and ready everything before continuing</strong>. Some actions taken on the next few steps can be detrimental if followed in the middle of the year. Once you are ready to proceed, click 'Begin' below.</p>
10+
<a href="#" data-module="newYear" data-step="welcome" class="btn btn-primary btn-new-next center-block"><span class="glyphicon glyphicon-ok"></span> Begin</a>
11+
</div>
12+
<div id="new-clear" style="display: none;">
13+
<h3 class="page-title">Clear Active Members and Floor Roster</h3>
14+
<p>This is the scary part. In order to get everything ready for next year, we need to clear everyone from Active status and then clear the housing board. Once we get a fresh start, we will forward you onto the housing page to fill out the new housing board.</p>
15+
<a href="#" data-module="newYear" data-step="clear" class="btn btn-primary btn-new-next center-block"><span class="glyphicon glyphicon-erase"></span> Clear Active Group and Housing Board</a>
16+
</div>
17+
<div id="new-current" style="display: none;">
18+
<h3 class="page-title">Prune Current Students Group</h3>
19+
<p>Take a second and scroll down the list, remove anyone who has graduated. Anyone in this list who is in good standing can become active, so it is important it is correct.</p>
20+
<table class="table table-striped no-bottom-margin" data-module="table" data-searchable="true" data-sort-column="0" data-sort-order="asc" data-length-changable="true">
21+
<thead>
22+
<tr>
23+
<th>Name</th>
24+
<th>Remove</th>
25+
</tr>
26+
</thead>
27+
<tbody>
28+
{% for student in current_students %}
29+
<tr>
30+
<td id="row-{{student.uid}}">{{student.displayName}}</td>
31+
<td width=100px>
32+
<a href="#" data-module="newYear" data-uid="{{student.uid}}">
33+
<span id="rem-{{student.uid}}" class="glyphicon glyphicon-remove red align-center" style="width: 100%"></span>
34+
<span id="add-{{student.uid}}" class="glyphicon glyphicon-plus green align-center" style="width: 100%; display: none;"></span>
35+
</a>
36+
</td>
37+
</tr>
38+
{% endfor %}
39+
</tbody>
40+
</table>
41+
<a href="#" data-module="newYear" data-step="current" class="btn btn-primary btn-new-next center-block"><span class="glyphicon glyphicon-ok"></span> Next Step</a>
42+
</div>
43+
<div id="new-housing" style="display: none;">
44+
<h3 class="page-title">That was easy!</h3>
45+
<p>The next and final step is to go through and populate the housing board, the button below will even take you there. Just a note: adding people will automatically mark them as active, since they will be charged dues.</p>
46+
<a href="/housing" class="btn btn-primary btn-new-next center-block"><span class="glyphicon glyphicon-ok"></span> Onward and Upward!</a>
47+
</div>
48+
</div>
49+
{% endblock %}

conditional/util/ldap.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,18 @@ def ldap_set_inactive(account):
121121
ldap_get_member.cache_clear()
122122

123123

124+
def ldap_set_current_student(account):
125+
_ldap_add_member_to_group(account, 'current_student')
126+
ldap_get_current_students.cache_clear()
127+
ldap_get_member.cache_clear()
128+
129+
130+
def ldap_set_non_current_student(account):
131+
_ldap_remove_member_from_group(account, 'current_student')
132+
ldap_get_current_students.cache_clear()
133+
ldap_get_member.cache_clear()
134+
135+
124136
def ldap_get_roomnumber(account):
125137
try:
126138
return account.roomNumber
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import FetchUtil from '../utils/fetchUtil';
2+
import Exception from "../exceptions/exception";
3+
import FetchException from "../exceptions/fetchException";
4+
import sweetAlert from "../../../node_modules/bootstrap-sweetalert/dev/sweetalert.es6.js"; // eslint-disable-line max-len
5+
6+
export default class NewYear {
7+
constructor(link) {
8+
this.link = link;
9+
this.step = this.link.dataset.step;
10+
this.uid = this.link.dataset.uid;
11+
12+
this.endpoints = {
13+
housing: '/housing',
14+
active: '/manage/active',
15+
current: '/manage/current/'
16+
};
17+
18+
this.render();
19+
}
20+
render() {
21+
this.link.addEventListener('click', e => {
22+
e.preventDefault();
23+
24+
if (this.step === "welcome") {
25+
$('#new-welcome').fadeOut(() => {
26+
$("#new-clear").fadeIn();
27+
});
28+
} else if (this.step === "clear") {
29+
FetchUtil.fetchWithWarning(this.endpoints.active, {
30+
method: 'DELETE',
31+
warningText: "This will clear active members and room assignments!",
32+
successText: "Data successfully cleared."}, () => {
33+
fetch(this.endpoints.housing, {
34+
method: 'DELETE'
35+
})
36+
.then($('#new-clear').fadeOut(() => {
37+
$("#new-current").fadeIn();
38+
})
39+
).catch(error => {
40+
sweetAlert("Uh oh...", "We're having trouble submitting that " +
41+
"action right now. Please try again later.", "error");
42+
throw new Exception(FetchException.REQUEST_FAILED, error);
43+
});
44+
});
45+
} else if (this.uid) {
46+
if ($('#rem-' + this.uid).is(":visible")) {
47+
fetch(this.endpoints.current + this.uid, {
48+
method: 'DELETE'
49+
}).then(() => {
50+
$('#rem-' + this.uid).hide();
51+
$('#add-' + this.uid).show();
52+
var userRow = $('#row-' + this.uid)[0];
53+
userRow.style.setProperty("text-decoration", "line-through");
54+
}).catch(error => {
55+
sweetAlert("Uh oh...", "We're having trouble submitting that " +
56+
"action right now. Please try again later.", "error");
57+
throw new Exception(FetchException.REQUEST_FAILED, error);
58+
});
59+
} else {
60+
fetch(this.endpoints.current + this.uid, {
61+
method: 'POST'
62+
}).then(() => {
63+
$('#add-' + this.uid).hide();
64+
$('#rem-' + this.uid).show();
65+
var lineRow = $('#row-' + this.uid)[0];
66+
lineRow.style.setProperty("text-decoration", "none");
67+
}).catch(error => {
68+
sweetAlert("Uh oh...", "We're having trouble submitting that " +
69+
"action right now. Please try again later.", "error");
70+
throw new Exception(FetchException.REQUEST_FAILED, error);
71+
});
72+
}
73+
} else if (this.step === "current") {
74+
$('#new-current').fadeOut(function() {
75+
$("#new-housing").fadeIn();
76+
});
77+
}
78+
});
79+
}
80+
}

frontend/stylesheets/pages/_management.scss

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
.switch-label {
2-
display: inline-block;
3-
padding: 40px 10px;
2+
display: block;
3+
padding: 17px 10px 10px;
44
text-align: center;
55
}
66

7+
.btn-new-year {
8+
margin-top: 30px;
9+
}
10+
11+
.btn-new-next {
12+
margin: 30px 0;
13+
}
14+
715
.upload-title {
816
padding-top: 20px;
917
height: 55px;

frontend/stylesheets/partials/_global.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,7 @@ tr {
8888
float: none;
8989
vertical-align: middle;
9090
}
91+
92+
.hidden {
93+
display: none;
94+
}

0 commit comments

Comments
 (0)