diff --git a/app/internal/agenda_events.py b/app/internal/agenda_events.py index a7053a46..ccd4bb23 100644 --- a/app/internal/agenda_events.py +++ b/app/internal/agenda_events.py @@ -1,6 +1,6 @@ import datetime from datetime import date, timedelta -from typing import Iterator, List, Optional, Union +from typing import Dict, Iterator, List, Optional, Tuple, Union import arrow from sqlalchemy.orm import Session @@ -89,3 +89,28 @@ def get_events_in_time_frame( """Yields all user's events in a time frame.""" events = get_all_user_events(db, user_id) yield from filter_dates(events, start_date, end_date) + + +def get_events_for_the_week(db: Session, user_id: int + ) -> Tuple[Union[Iterator[Event], list], Dict]: + WEEK_DAYS = 7 + start_date = date.today() + end_date = start_date + timedelta(days=WEEK_DAYS - 1) + + events_this_week = get_events_per_dates( + db, user_id, start_date, end_date + ) + events_for_graph = { + str(start_date + timedelta(i)): 0 for i in range(WEEK_DAYS) + } + return events_this_week, events_for_graph + + +def make_dict_for_graph_data(db: Session, user_id: int) -> Dict[str, int]: + """create a dict with number of events per day for current week""" + events_this_week, events_for_graph = get_events_for_the_week(db, user_id) + + for event_obj in events_this_week: + event_date = event_obj.start.date() + events_for_graph[str(event_date)] += 1 + return events_for_graph diff --git a/app/routers/agenda.py b/app/routers/agenda.py index c25012ce..6cc5a7af 100644 --- a/app/routers/agenda.py +++ b/app/routers/agenda.py @@ -1,5 +1,6 @@ from collections import defaultdict from datetime import date, timedelta +import json from typing import Optional, Tuple from fastapi import APIRouter, Depends, Request @@ -38,6 +39,7 @@ def agenda( """Route for the agenda page, using dates range or exact amount of days.""" user_id = 1 # there is no user session yet, so I use user id- 1. + start_date, end_date = calc_dates_range_for_agenda( start_date, end_date, days ) @@ -46,15 +48,19 @@ def agenda( db, user_id, start_date, end_date ) events = defaultdict(list) + for event_obj in events_objects: event_duration = agenda_events.get_time_delta_string( event_obj.start, event_obj.end ) events[event_obj.start.date()].append((event_obj, event_duration)) - + events_for_graph = json.dumps( + agenda_events.make_dict_for_graph_data(db, user_id) + ) return templates.TemplateResponse("agenda.html", { "request": request, "events": events, "start_date": start_date, "end_date": end_date, + "events_for_graph": events_for_graph, }) diff --git a/app/static/graph.js b/app/static/graph.js new file mode 100644 index 00000000..0a2b7daf --- /dev/null +++ b/app/static/graph.js @@ -0,0 +1,49 @@ +function busiestDayOfTheWeekGraph(events) { + events = JSON.parse(events); + + const data = Object.values(events); + const labels = Object.keys(events); + const ctx = document.getElementById("myChart"); + ctx.style.backgroundColor = "rgba(255, 255, 255, 1)"; + const myChart = new Chart(ctx, { + type: "bar", + data: { + labels: labels, + datasets: [{ + label: "# Events", + data: data, + backgroundColor: [ + "rgba(255, 99, 132, 0.2)", + "rgba(54, 162, 235, 0.2)", + "rgba(255, 206, 86, 0.2)", + "rgba(75, 192, 192, 0.2)", + "rgba(153, 102, 255, 0.2)", + "rgba(255, 159, 64, 0.2)", + "rgba(200, 130, 40, 0.2)", + "rgba(255, 99, 132, 0.2)" + ], + borderColor: [ + "rgba(255, 99, 132, 1)", + "rgba(54, 162, 235, 1)", + "rgba(255, 206, 86, 1)", + "rgba(75, 192, 192, 1)", + "rgba(153, 102, 255, 1)", + "rgba(255, 159, 64, 1)", + "rgba(200, 130, 64, 1)", + "rgba(255, 99, 132, 1)" + ], + borderWidth: 1 + }] + } + }); +} + +function addEventsAfterPageLoaded() { + const element = document.getElementsByClassName("graph")[0]; + element.addEventListener("click", function() { + let eventsPerDateData = element.name; + busiestDayOfTheWeekGraph(eventsPerDateData); + }, false); +} + +document.addEventListener("DOMContentLoaded", addEventsAfterPageLoaded); \ No newline at end of file diff --git a/app/templates/agenda.html b/app/templates/agenda.html index f86e5a38..693c5eee 100644 --- a/app/templates/agenda.html +++ b/app/templates/agenda.html @@ -30,6 +30,15 @@
{{ gettext("Next 30 days") }}
+
+ +
+ + +
+ +
+
diff --git a/app/templates/base.html b/app/templates/base.html index fd313c61..5d211ad5 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -87,6 +87,7 @@ + diff --git a/tests/test_agenda_internal.py b/tests/test_agenda_internal.py index 277204dc..8f38153d 100644 --- a/tests/test_agenda_internal.py +++ b/tests/test_agenda_internal.py @@ -44,3 +44,26 @@ def test_get_events_per_dates_failure(self, yesterday_event, session): end=date.today(), ) assert list(events) == [] + + def test_make_dict_for_graph_data(self, today_event, session): + events_for_graph = agenda_events.make_dict_for_graph_data( + session, + user_id=today_event.owner_id, + ) + assert isinstance(events_for_graph, dict) + + def test_get_events_for_the_week_success(self, today_event, session): + events, events_for_graph = agenda_events.get_events_for_the_week( + session, + user_id=today_event.owner_id, + ) + assert isinstance(events_for_graph, dict) + assert list(events) == [today_event] + + def test_get_events_for_the_week_failure(self, yesterday_event, session): + events, events_for_graph = agenda_events.get_events_for_the_week( + session, + user_id=yesterday_event.owner_id, + ) + assert list(events) == [] + assert isinstance(events_for_graph, dict) diff --git a/tests/test_agenda_route.py b/tests/test_agenda_route.py index 1bd6682b..c3c633be 100644 --- a/tests/test_agenda_route.py +++ b/tests/test_agenda_route.py @@ -86,7 +86,7 @@ def test_agenda_between_two_dates( assert b"event 5" in resp.content assert b"event 6" not in resp.content - def test_agenda_start_bigger_than_end(self, agenda_test_client): + def test_agenda_start_bigger_than_end(self, agenda_test_client, session): start_date = self.today_date.date() end_date = (self.today_date - timedelta(days=2)).date() resp = agenda_test_client.get(