Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix list activity notifications #12386

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7d91c02
Fix last record query
AlexVelezLl Jul 1, 2024
3dcb132
Fix id related sorting with timestamp
AlexVelezLl Jul 1, 2024
beb1a1e
Avoid update contentSummaryLog completion_timestamp if already set
AlexVelezLl Jul 2, 2024
8c39b1a
Save completion_timestamp as lesson/resource ccompleted notification …
AlexVelezLl Jul 2, 2024
cdb559e
Fix sorting key in frontend and check empty summarized notifications
AlexVelezLl Jul 2, 2024
f244813
Calculate resource completion notification tiemstamp
AlexVelezLl Jul 3, 2024
a04d18f
Update notifications timestamp of the first and last created/complete…
AlexVelezLl Jul 3, 2024
e35acf7
Add check to completion_timestamp to determine if a resource have bee…
AlexVelezLl Jul 3, 2024
0cd4a36
Update help needed timestamp
AlexVelezLl Jul 3, 2024
9ff55fa
Refactor duplicated code and improve comments
AlexVelezLl Jul 4, 2024
a1eccbe
improve before/after filters with timestamps
AlexVelezLl Jul 4, 2024
92d6ccc
Refactor filter logic
AlexVelezLl Jul 4, 2024
29afe74
Add timestamp index in learner progress notification
AlexVelezLl Jul 4, 2024
f74a047
Fix frontend ordering and edge cases
AlexVelezLl Jul 8, 2024
3080ed6
Fix excercise resource notifications logged on first attempt
AlexVelezLl Jul 8, 2024
b1c77cd
Fix tests
AlexVelezLl Jul 8, 2024
dc29843
Refactor notifications tests and improve attemptlog testing
AlexVelezLl Jul 17, 2024
6b95d68
Add parse_summarylog tests with multiple resources in a lesson
AlexVelezLl Jul 17, 2024
2224dfb
Add create_summarylog tests with multiple resources in a lesson
AlexVelezLl Jul 17, 2024
b4755c2
test batch process summary log
AlexVelezLl Jul 17, 2024
39c6120
test batch attemptlogs
AlexVelezLl Jul 17, 2024
17ab6f7
Refactor
AlexVelezLl Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions kolibri/core/logger/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -823,8 +823,7 @@ def _update_summary_log(
summarylog = ContentSummaryLog.objects.get(
content_id=sessionlog.content_id, user=user
)
was_complete = summarylog.progress >= 1
AlexVelezLl marked this conversation as resolved.
Show resolved Hide resolved

was_complete = summarylog.completion_timestamp is not None
update_fields = self._update_content_log(
summarylog, end_timestamp, validated_data
)
Expand Down
8 changes: 4 additions & 4 deletions kolibri/core/notifications/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def finish_lesson_resource(summarylog, contentnode_id, lesson_id):
notifications = []
# Now let's check completed resources and lessons:
notification_completed = check_and_created_completed_resource(
lesson, summarylog.user_id, contentnode_id, summarylog.end_timestamp
lesson, summarylog.user_id, contentnode_id, summarylog.completion_timestamp
)
if notification_completed:
notifications.append(notification_completed)
Expand All @@ -328,7 +328,7 @@ def finish_lesson_resource(summarylog, contentnode_id, lesson_id):
).count()
if user_completed_resources == len(lesson_content_ids):
notification_completed = check_and_created_completed_lesson(
lesson, summarylog.user_id, summarylog.end_timestamp
lesson, summarylog.user_id, summarylog.completion_timestamp
)
if notification_completed:
notifications.append(notification_completed)
Expand Down Expand Up @@ -424,7 +424,7 @@ def parse_summarylog(summarylog):
for lesson, contentnode_id in lessons:
# Now let's check completed resources and lessons:
notification_completed = check_and_created_completed_resource(
lesson, summarylog.user_id, contentnode_id, summarylog.end_timestamp
lesson, summarylog.user_id, contentnode_id, summarylog.completion_timestamp
)
if notification_completed:
notifications.append(notification_completed)
Expand All @@ -440,7 +440,7 @@ def parse_summarylog(summarylog):
).count()
if user_completed == len(lesson_content_ids):
notification_completed = check_and_created_completed_lesson(
lesson, summarylog.user_id, summarylog.end_timestamp
lesson, summarylog.user_id, summarylog.completion_timestamp
)
if notification_completed:
notifications.append(notification_completed)
Expand Down
19 changes: 13 additions & 6 deletions kolibri/plugins/coach/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,18 @@ def get_queryset(self):
notifications_query = self.apply_group_filter(notifications_query)
after = self.check_after()
AlexVelezLl marked this conversation as resolved.
Show resolved Hide resolved
if after:
notifications_query = notifications_query.filter(id__gt=after)
# after is an id, so we need to get the notiication with that id, and filter by timestamp
after_timestamp = notifications_query.get(id=after).timestamp
notifications_query = notifications_query.filter(
timestamp__gt=after_timestamp
)
before = self.check_before()

if not after and not before:
try:
last_id_record = notifications_query.latest("id")
last_record = notifications_query.latest("timestamp")
# returns all the notifications 24 hours older than the latest
last_24h = last_id_record.timestamp - datetime.timedelta(days=1)
last_24h = last_record.timestamp - datetime.timedelta(days=1)
notifications_query = notifications_query.filter(
timestamp__gte=last_24h
)
Expand All @@ -212,12 +216,15 @@ def get_queryset(self):
limit = self.check_limit()
if before and limit:
AlexVelezLl marked this conversation as resolved.
Show resolved Hide resolved
# Don't allow arbitrary backwards lookups
notifications_query = notifications_query.filter(id__lt=before)
before_timestamp = notifications_query.get(id=before).timestamp
notifications_query = notifications_query.filter(
timestamp__lt=before_timestamp
)

return notifications_query

def annotate_queryset(self, queryset):
queryset = queryset.order_by("-id")
queryset = queryset.order_by("-timestamp")
limit = self.check_limit()
if limit:
return queryset[:limit]
Expand Down Expand Up @@ -257,7 +264,7 @@ def list(self, request, *args, **kwargs):
limit = self.check_limit()
if limit:
# If we are limiting responses, check if more results are available
more_results = queryset.order_by("-id")[limit:].exists()
more_results = queryset.order_by("-timestamp")[limit:].exists()

return Response(
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import maxBy from 'lodash/maxBy';
import minBy from 'lodash/minBy';
import sortBy from 'lodash/sortBy';
import uniqBy from 'lodash/uniqBy';
import notificationsResource from '../../apiResources/notifications';
Expand All @@ -12,10 +13,13 @@ export default {
},
mutations: {
SET_NOTIFICATIONS(state, notifications) {
state.notifications = sortBy([...notifications], '-id');
state.notifications = sortBy([...notifications], '-timestamp');
},
INSERT_NOTIFICATIONS(state, notifications) {
state.notifications = uniqBy(sortBy([...state.notifications, ...notifications], '-id'), 'id');
state.notifications = uniqBy(
sortBy([...state.notifications, ...notifications], '-timestamp'),
'id',
);
},
SET_CURRENT_CLASSROOM_ID(state, classroomId) {
state.currentClassroomId = classroomId;
Expand All @@ -26,8 +30,7 @@ export default {
summarizedNotifications,
maxNotificationIndex(state) {
if (state.notifications.length > 0) {
// IDs are being converted to strings for some reason
return maxBy(state.notifications, n => Number(n.id)).id;
return maxBy(state.notifications, n => new Date(n.timestamp)).id;
}
return 0;
},
Expand All @@ -54,6 +57,7 @@ export default {
if (!store.state.poller) {
store.dispatch('startingPolling', { coachesPolling: data.coaches_polling });
}
store.dispatch('checkEmptySummarizedNotifications');
})
.catch(() => {
if (!store.state.poller) {
Expand Down Expand Up @@ -87,7 +91,7 @@ export default {
},
moreNotificationsForClass(store, params) {
const classroomId = store.state.currentClassroomId;
const lastNotification = store.state.notifications.slice(-1)[0];
AlexVelezLl marked this conversation as resolved.
Show resolved Hide resolved
const lastNotification = minBy(store.state.notifications, n => new Date(n.timestamp));
// don't fetch if no current classroom
if (!classroomId || !lastNotification || lastNotification.id <= 1) {
return Promise.resolve(false);
Expand All @@ -106,6 +110,9 @@ export default {
.then(data => {
if (data.results.length > 0) {
store.commit('INSERT_NOTIFICATIONS', data.results);
if (data.more_results) {
store.dispatch('checkEmptySummarizedNotifications');
}
return data.more_results;
}
return false;
Expand All @@ -123,5 +130,10 @@ export default {
});
}, timeout);
},
checkEmptySummarizedNotifications(store) {
if (store.getters.summarizedNotifications.length === 0) {
store.dispatch('moreNotificationsForClass');
}
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,6 @@
const params = {
...this.filterParam,
};
if (this.notifications.length) {
params.before = this.notifications.slice(-1)[0].id;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this been removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The before param is already set inside the moreNotificationsForClass action https://github.com/AlexVelezLl/kolibri/blob/cdb559e453c0c6468ef95d4c97ad7bfdb342d9ec/kolibri/plugins/coach/assets/src/modules/coachNotifications/index.js#L104. So it was repeated code and thought it was better to keep the one in the moreNotificationsForClass action,

}
this.moreNotificationsForClass(params).then(moreResults => {
this.moreResults = moreResults;
this.loading = false;
Expand Down