Skip to content

Commit

Permalink
Add capability to download data for analysis (#158)
Browse files Browse the repository at this point in the history
<!--- Please write your PR name in the present imperative tense.
Examples of that tense are: "Fix issue in the dispatcher where…",
"Improve our handling of…", etc." -->
<!-- For more information on Pull Requests, you can reference here:
https://success.vanillaforums.com/kb/articles/228-using-pull-requests-to-contribute
-->
## Describe Your Changes

- created downloadable dataTables displayed at
`/admin/dashboard_analysis`

## Non-Obvious Technical Information


## Checklist Before Requesting a Review
- [x] The code runs successfully.


<img width="1512" alt="Screenshot 2024-03-03 at 3 26 59 PM"
src="https://github.com/prijatelilab/PrijateliTree/assets/25271399/c5bfefec-4305-43ab-ab04-71e251676806">
  • Loading branch information
anisfeld authored Mar 3, 2024
1 parent 1777d59 commit 3e4c936
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 1 deletion.
39 changes: 38 additions & 1 deletion prijateli_tree/app/routers/administration.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from prijateli_tree.app.database import (
Game,
GameAnswer,
GamePlayer,
GameSession,
GameSessionPlayer,
Expand Down Expand Up @@ -483,7 +484,7 @@ def add_students(
detail="Upload file is missing expected fields",
)

for index, student in student_df.iterrows():
for _, student in student_df.iterrows():
student_in = User(
created_by=user.id,
**student,
Expand All @@ -510,3 +511,39 @@ def add_students(
redirect_url,
status_code=HTTPStatus.FOUND,
)


@router.get("/dashboard_analysis", response_class=HTMLResponse)
def analysis_dashboard(
request: Request,
user=Depends(login_manager.optional),
db: Session = Depends(get_db),
) -> Response:
if user is None:
return RedirectResponse("login", status_code=HTTPStatus.FOUND)

games = db.query(Game).all()
answers = db.query(GameAnswer).all()
students = db.query(User).filter_by(role=ROLE_STUDENT).all()
game_players = db.query(GamePlayer).all()
# student_dict = {}
# for s in students:
# student_dict[s.id] = s

# for s in sessions:
# players: [str] = []
# for p in s.players:
# players.append(student_dict[p.user_id].name_str)
# s.player_string = ", ".join(players)

return templates.TemplateResponse(
"administration/analysis_dashboard.html",
{
"request": request,
"user": user,
"games": games,
"students": students,
"game_players": game_players,
"answers": answers,
},
)
185 changes: 185 additions & 0 deletions prijateli_tree/app/templates/administration/analysis_dashboard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
{% extends "base.html" %}
{% block title %}
PrijateliTree - Analysis Dashboard
{% endblock title %}
{% block helper_script %}
<script>
$(document).ready(function () {
$('#session_history').DataTable({
layout: {
topStart: {buttons: ['csvHtml5']}
}
})
$('#answers').DataTable({
layout: {
topStart: {buttons: ['csvHtml5']}
}
})
$('#signals').DataTable({
layout: {
topStart: {buttons: ['csvHtml5']}
}
})
$('#students').DataTable({
layout: {
topStart: {buttons: ['csvHtml5']}
}
})
});
</script>
{% endblock helper_script %}
{% block content %}
<div class="container-fluid">
<div class="row">
<!--Begin Table -->
<div class="offset-md-1 col-md-10 offset-xl-2 col-xl-8 table-container">
<h2>Game History</h2>
Each row is a session-game
<table id="session_history"
class="table table-hover table-bordered caption-top text-center">
<caption>Game History</caption>
<thead>
<tr>
<th>session id</th>
<th>game id</th>
<th>network type</th>
<th>names hidden</th>
<th>practice</th>
<th>n rounds</th>
<th>network visible</th>
<th>points</th>
</tr>
</thead>
<tbody class="table-group-divider">
{% if games |length == 0 %}
<tr class="empty-table">
<td colspan="5">There are no game types currently in the system.</td>
</tr>
{% endif %}
{% for g in games %}
<tr>
<td>{{ g.game_session_id }}</td>
<td>{{ g.id }}</td>
<td>{{ g.game_type.network }}</td>
<td>{{ g.game_type.names_hidden }}</td>
<td>{{ g.practice }}</td>
<td>{{ g.rounds }}</td>
<td>{{ g.is_network_visible }}</td>
<td>{{ g.winning_score }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!--End Table -->
<!--Begin Table -->
<div class="offset-md-1 col-md-10 offset-xl-2 col-xl-8 table-container">
<h2>Game Answers</h2>
Each row is a guess by player X in game Y during round Z
<table id="answers"
class="table table-hover table-bordered caption-top text-center">
<caption>Game Answers</caption>
<thead>
<tr>
<th>session id</th>
<th>game id</th>
<th>user id</th>
<th>position</th>
<th>round</th>
<th>guess</th>
<th>correct</th>
</tr>
</thead>
<tbody class="table-group-divider">
{% if answers|length == 0 %}
<tr class="empty-table">
<td colspan="5">There are no game types currently in the system.</td>
</tr>
{% endif %}
{% for a in answers %}
<tr>
<td>{{ a.player.game.game_session_id }}</td>
<td>{{ a.player.game_id }}</td>
<td>{{ a.player.user.id }}</td>
<td>{{ a.player.position }}</td>
<td>{{ a.round }}</td>
<td>{{ a.player_answer }}</td>
<td>{{ a.correct_answer }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!--End Table -->
<!--Begin USERS Table -->
<div class="offset-md-1 col-md-10 offset-xl-2 col-xl-8 table-container">
<h2>Signals</h2>
Each row is the signal shown to player X in game Y
<table id="signals"
class="table table-hover table-bordered caption-top text-center">
<caption>Signals</caption>
<thead>
<tr>
<th>session id</th>
<th>game id</th>
<th>user id</th>
<th>position</th>
<th>round</th>
<th>signal</th>
</tr>
</thead>
<tbody class="table-group-divider">
{% if answers|length == 0 %}
<tr class="empty-table">
<td colspan="5">There are no game types currently in the system.</td>
</tr>
{% endif %}
{% for gp in game_players %}
<tr>
<td>{{ gp.game.game_session_id }}</td>
<td>{{ gp.game.id }}</td>
<td>{{ gp.user.id }}</td>
<th>{{ gp.position }}</th>
<td>0</td>
<td>{{ gp.initial_ball }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!--End Table -->
<!--Begin USERS Table -->
<div class="offset-md-1 col-md-10 offset-xl-2 col-xl-8 table-container">
<h2>Students</h2>
Each row is mapping from internal id to cid
<table id="students"
class="table table-hover table-bordered caption-top text-center">
<caption>Students</caption>
<thead>
<tr>
<th>user id</th>
<th>cid</th>
</tr>
</thead>
<tbody class="table-group-divider">
{% if answers|length == 0 %}
<tr class="empty-table">
<td colspan="5">There are no game types currently in the system.</td>
</tr>
{% endif %}
{% for s in students %}
<tr>
<td>{{ s.id }}</td>
<td>{{ s.qualtrics_id }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!--End Table -->
</div>
</div>
{% endblock content %}
<form class="d-flex" action='{{ url_for("logout") }}'>
<button class="float-end btn btn-primary" type="submit">Logout</button>
</form>

0 comments on commit 3e4c936

Please sign in to comment.