diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 4fed9bc57cdf05f45aa7ba8faac411e9995fe4ff..c4910d94b5b1e282a9bb6b1ede5c930df33d3c6c 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,6 +9,11 @@ and this project adheres to `Semantic Versioning`_.
 Unreleased
 ----------
 
+Fixed
+~~~~~
+
+* Remove lessons replaced by events from "My timetable"
+
 `3.0.1`_ - 2023-07-20
 ---------------------
 
diff --git a/aleksis/apps/chronos/frontend/components/SelectTimetable.vue b/aleksis/apps/chronos/frontend/components/SelectTimetable.vue
index 069d74c56942509bae47aaac844cdf5d2205d383..fb98d1f56c51d4261502df5d8ec2889e39e6445c 100644
--- a/aleksis/apps/chronos/frontend/components/SelectTimetable.vue
+++ b/aleksis/apps/chronos/frontend/components/SelectTimetable.vue
@@ -5,8 +5,9 @@ export default {
   name: "SelectTimetable",
   props: {
     value: {
-      type: String | null,
-      required: true,
+      type: String,
+      required: false,
+      default: null,
     },
     availableTimetables: {
       type: Array,
diff --git a/aleksis/apps/chronos/frontend/components/Timetable.vue b/aleksis/apps/chronos/frontend/components/Timetable.vue
index d685684be91e9e63b7c1e2dc0e991ee7b098b7cf..e4fca5dfb63f26597cd534315fed8f32b9b8a2de 100644
--- a/aleksis/apps/chronos/frontend/components/Timetable.vue
+++ b/aleksis/apps/chronos/frontend/components/Timetable.vue
@@ -115,7 +115,7 @@ export default {
           <select-timetable
             v-model="selected"
             @input="selectDialog = false"
-            :availableTimetables="availableTimetables"
+            :available-timetables="availableTimetables"
           />
         </v-card>
       </v-dialog>
@@ -124,7 +124,7 @@ export default {
         <v-card>
           <select-timetable
             v-model="selected"
-            :availableTimetables="availableTimetables"
+            :available-timetables="availableTimetables"
           />
         </v-card>
       </v-col>
@@ -193,7 +193,7 @@ export default {
             </div>
           </div>
           <calendar-with-controls
-            :calendar-feeds="[{ name: 'lesson' }]"
+            :calendar-feeds="[{ name: 'lesson' }, { name: 'supervision' }]"
             :params="{ type: selected.type, id: selected.objId }"
           />
         </v-card>
diff --git a/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue b/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue
index f11275541ae2f89febb63d5f9ed32485260232a1..0c9311450f0c7d8c3e922743f1403382da1148ce 100644
--- a/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue
+++ b/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue
@@ -3,7 +3,7 @@
     v-bind="$props"
     :color="currentSubject ? currentSubject.colour_bg : null"
     without-location
-      >
+  >
     <template #title>
       <div
         :style="{
diff --git a/aleksis/apps/chronos/frontend/components/calendar_feeds/details/SupervisionDetails.vue b/aleksis/apps/chronos/frontend/components/calendar_feeds/details/SupervisionDetails.vue
new file mode 100644
index 0000000000000000000000000000000000000000..7d6455a054fd8d7a46433ea5ad4693e4c40ff43e
--- /dev/null
+++ b/aleksis/apps/chronos/frontend/components/calendar_feeds/details/SupervisionDetails.vue
@@ -0,0 +1,109 @@
+<template>
+  <base-calendar-feed-details
+    v-bind="$props"
+    :color="currentSubject ? currentSubject.colour_bg : null"
+    without-location
+  >
+    <template #title>
+      <div
+        :style="{
+          color: currentSubject ? currentSubject.colour_fg || 'white' : 'white',
+        }"
+      >
+        <lesson-event-subject :event="selectedEvent" />
+      </div>
+    </template>
+    <template #badge>
+      <cancelled-calendar-status-chip
+        v-if="selectedEvent.meta.cancelled"
+        class="ml-4"
+      />
+      <calendar-status-chip
+        color="warning"
+        icon="mdi-clipboard-alert-outline"
+        v-else-if="selectedEvent.meta.amended"
+        class="ml-4"
+      >
+        {{ $t("chronos.event.current_changes") }}
+      </calendar-status-chip>
+    </template>
+    <template #description>
+      <v-divider inset />
+      <v-list-item>
+        <v-list-item-icon>
+          <v-icon color="primary">mdi-human-male-board </v-icon>
+        </v-list-item-icon>
+        <v-list-item-content>
+          <v-list-item-title>
+            <span v-if="teachers.length === 0" class="body-2 text--secondary">{{
+              $t("chronos.event.no_teacher")
+            }}</span>
+            <lesson-related-object-chip
+              v-for="teacher in teachers"
+              :status="teacher.status"
+              :key="teacher.id"
+              new-icon="mdi-account-plus-outline"
+              >{{ teacher.full_name }}</lesson-related-object-chip
+            >
+          </v-list-item-title>
+        </v-list-item-content>
+      </v-list-item>
+      <v-list-item>
+        <v-list-item-icon>
+          <v-icon color="primary">mdi-door </v-icon>
+        </v-list-item-icon>
+        <v-list-item-content>
+          <v-list-item-title>
+            <span v-if="rooms.length === 0" class="body-2 text--secondary">{{
+              $t("chronos.event.no_room")
+            }}</span>
+            <lesson-related-object-chip
+              v-for="room in rooms"
+              :status="room.status"
+              :key="room.id"
+              new-icon="mdi-door-open"
+              >{{ room.name }}</lesson-related-object-chip
+            >
+          </v-list-item-title>
+        </v-list-item-content>
+      </v-list-item>
+      <v-divider inset />
+      <v-list-item v-if="selectedEvent.meta.comment">
+        <v-list-item-content>
+          <v-list-item-title>
+            <v-alert
+              dense
+              outlined
+              type="warning"
+              icon="mdi-information-outline"
+            >
+              {{ selectedEvent.meta.comment }}
+            </v-alert>
+          </v-list-item-title>
+        </v-list-item-content>
+      </v-list-item>
+    </template>
+  </base-calendar-feed-details>
+</template>
+
+<script>
+import calendarFeedDetailsMixin from "aleksis.core/mixins/calendarFeedDetails.js";
+import BaseCalendarFeedDetails from "aleksis.core/components/calendar/BaseCalendarFeedDetails.vue";
+import CalendarStatusChip from "aleksis.core/components/calendar/CalendarStatusChip.vue";
+import CancelledCalendarStatusChip from "aleksis.core/components/calendar/CancelledCalendarStatusChip.vue";
+
+import LessonRelatedObjectChip from "../../LessonRelatedObjectChip.vue";
+import lessonEvent from "../mixins/lessonEvent";
+import LessonEventSubject from "../../LessonEventSubject.vue";
+export default {
+  name: "LessonDetails",
+  components: {
+    LessonEventSubject,
+    LessonRelatedObjectChip,
+    BaseCalendarFeedDetails,
+    CalendarStatusChip,
+    CancelledCalendarStatusChip,
+  },
+  mixins: [calendarFeedDetailsMixin, lessonEvent],
+};
+</script>
diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py
index 165e9b10e0ee2e49595d4627c8f2642b2c179d5d..11ba2702e648d0eff7e6eb5c29a3748a8f8329c5 100644
--- a/aleksis/apps/chronos/models.py
+++ b/aleksis/apps/chronos/models.py
@@ -1583,7 +1583,7 @@ class LessonEvent(CalendarEvent):
     @classmethod
     def get_objects(cls, request, params=None) -> Iterable:
         """Return all objects that should be included in the calendar."""
-        objs = super().get_objects(request, params)
+        objs = super().get_objects(request, params).not_instance_of(SupervisionEvent)
         if params:
             obj_id = int(params.get("id", 0))
             type = params.get("type", None)
@@ -1606,6 +1606,8 @@ class SupervisionEvent(LessonEvent):
     name = "supervision"
     verbose_name = _("Supervisions")
 
+    objects = PolymorphicCurrentSiteManager.from_queryset(LessonEventQuerySet)()
+
     @classmethod
     def value_title(cls, reference_object: "LessonEvent", request) -> str:
         """Get the title of the event."""
@@ -1621,7 +1623,7 @@ class SupervisionEvent(LessonEvent):
     @classmethod
     def get_objects(cls, request, params=None) -> Iterable:
         """Return all objects that should be included in the calendar."""
-        objs = super().get_objects(request, params)
+        objs = cls.objects.instance_of(cls)
         if params:
             obj_id = int(params.get("id", 0))
             type = params.get("type", None)
diff --git a/aleksis/apps/chronos/tests/regression/test_regression.py b/aleksis/apps/chronos/tests/regression/test_regression.py
deleted file mode 100644
index 0b4a71838cdfb1fafe2600022868558d70b9bd14..0000000000000000000000000000000000000000
--- a/aleksis/apps/chronos/tests/regression/test_regression.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from datetime import time, timedelta
-
-from django.contrib.auth import get_user_model
-from django.utils import timezone
-
-import pytest
-
-from aleksis.apps.chronos.util.chronos_helpers import get_rooms, get_teachers
-from aleksis.core.models import Group, Person, Room, SchoolTerm
-
-pytestmark = pytest.mark.django_db
-
-
-from aleksis.apps.chronos.models import Lesson, LessonPeriod, Subject, TimePeriod, ValidityRange
-
-
-def test_rooms_teachers_only_from_current_school_term():
-    User = get_user_model()
-
-    user = User.objects.create(username="test", is_staff=True, is_superuser=True)
-    person_user = Person.objects.create(user=user, first_name="Test", last_name="User")
-
-    correct_school_term = SchoolTerm.objects.create(
-        date_start=timezone.now() - timedelta(days=1),
-        date_end=timezone.now() + timedelta(days=1),
-        name="Correct school term",
-    )
-    wrong_school_term = SchoolTerm.objects.create(
-        date_start=timezone.now() - timedelta(days=3),
-        date_end=timezone.now() - timedelta(days=2),
-        name="Wrong school term",
-    )
-
-    correct_validity = ValidityRange.objects.create(
-        school_term=correct_school_term,
-        date_start=correct_school_term.date_start,
-        date_end=correct_school_term.date_end,
-        name="Correct validity",
-    )
-    wrong_validity = ValidityRange.objects.create(
-        school_term=wrong_school_term,
-        date_start=wrong_school_term.date_start,
-        date_end=wrong_school_term.date_end,
-        name="Wrong validity",
-    )
-
-    subject = Subject.objects.create(name="Test subject", short_name="TS")
-    time_period = TimePeriod.objects.create(
-        weekday=0, period=1, time_start=time(8, 0), time_end=time(9, 0)
-    )
-
-    correct_person = Person.objects.create(first_name="Correct", last_name="Person")
-    wrong_person = Person.objects.create(first_name="Wrong", last_name="Person")
-
-    correct_lesson = Lesson.objects.create(validity=correct_validity, subject=subject)
-    correct_lesson.teachers.add(correct_person)
-    wrong_lesson = Lesson.objects.create(validity=wrong_validity, subject=subject)
-    wrong_lesson.teachers.add(wrong_person)
-
-    correct_room = Room.objects.create(name="Correct room", short_name="cr")
-    wrong_room = Room.objects.create(name="Wrong room", short_name="wr")
-
-    correct_lesson_period = LessonPeriod.objects.create(
-        lesson=correct_lesson, period=time_period, room=correct_room
-    )
-    wrong_lesson_period = LessonPeriod.objects.create(
-        lesson=wrong_lesson, period=time_period, room=wrong_room
-    )
-
-    rooms = get_rooms(user)
-    assert correct_room in rooms
-    assert wrong_room not in rooms
-
-    teachers = get_teachers(user)
-    assert correct_person in teachers
-    assert wrong_person not in teachers
diff --git a/aleksis/apps/chronos/util/build.py b/aleksis/apps/chronos/util/build.py
index a6c89a347ffdf2cc10e01b705fcad746eb7535e2..f79ecf6484dbaa18f22447ad9a0a0c57160add96 100644
--- a/aleksis/apps/chronos/util/build.py
+++ b/aleksis/apps/chronos/util/build.py
@@ -34,7 +34,7 @@ def build_timetable(
         type_ = obj.timetable_type
 
     is_week = False
-    if type(date_ref) == CalendarWeek:
+    if isinstance(date_ref, CalendarWeek):
         is_week = True
 
     if type_ is None:
@@ -361,17 +361,22 @@ def build_timetable(
                     continue
 
                 events_for_this_period = events_per_period.get(period, [])
+                events_for_replacement_for_this_period = events_for_replacement_per_period.get(
+                    period, []
+                )
                 lesson_periods_for_this_period = lesson_periods_per_period.get(period, [])
 
                 # Add lesson periods
                 if lesson_periods_for_this_period:
-                    if events_for_this_period:
+                    if events_for_replacement_for_this_period:
                         # If there is a event in this period,
                         # we have to check whether the actual lesson is taking place.
 
                         lesson_periods_to_keep = []
                         for lesson_period in lesson_periods_for_this_period:
-                            if not lesson_period.is_replaced_by_event(events_for_this_period):
+                            if not lesson_period.is_replaced_by_event(
+                                events_for_replacement_for_this_period
+                            ):
                                 lesson_periods_to_keep.append(lesson_period)
                         col += lesson_periods_to_keep
                     else:
diff --git a/aleksis/apps/chronos/views.py b/aleksis/apps/chronos/views.py
index fdb6def85b24e1f166ff7ee1139e04b0e4bfe9a5..a7ae9b77b322c00f41860c39a3f6cc7ae6376687 100644
--- a/aleksis/apps/chronos/views.py
+++ b/aleksis/apps/chronos/views.py
@@ -139,7 +139,7 @@ def timetable(
 
     el = get_el_by_pk(request, type_, pk, prefetch=True)
 
-    if type(el) == HttpResponseNotFound:
+    if isinstance(el, HttpResponseNotFound):
         return HttpResponseNotFound()
 
     type_ = TimetableType.from_string(type_)
diff --git a/pyproject.toml b/pyproject.toml
index 2ea4b3341d1f090797c2e14c377e3f33636d308c..32832395ff78f72b83016625a3bfd35612da15bf 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -66,7 +66,6 @@ safety = "^2.3.5"
 flake8 = "^6.0.0"
 flake8-django = "~1.2"
 flake8-fixme = "^1.1.1"
-flake8-mypy = "^17.8.0"
 flake8-bandit = "^4.1.1"
 flake8-builtins = "^2.0.0"
 flake8-docstrings = "^1.5.0"
diff --git a/tox.ini b/tox.ini
index 6e4b77ab1ded935257117696975c2150772cd85c..85c2494a5a2f5480bb05d48781edfaa74803eeab 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,7 @@ skip_missing_interpreters = true
 envlist = py39,py310,py311
 
 [testenv]
-whitelist_externals = poetry
+allowlist_externals = poetry
 skip_install = true
 envdir = {toxworkdir}/globalenv
 commands_pre =
@@ -68,18 +68,6 @@ known_django = django
 skip = migrations
 sections = FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
 
-[mypy]
-plugins = mypy_django_plugin.main
-python_version = 3.8
-platform = linux
-show_column_numbers = True
-follow_imports = skip
-ignore_missing_imports = True
-cache_dir = /dev/null
-
-[mypy.plugins.django-stubs]
-django_settings_module = aleksis.core.settings
-
 [pytest]
 DJANGO_SETTINGS_MODULE = aleksis.core.settings
 junit_family = legacy