diff --git a/aleksis/apps/chronos/frontend/components/AmendLesson.vue b/aleksis/apps/chronos/frontend/components/AmendLesson.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f43faa3a31d0b4d44a8459a63a0b99ae68228743
--- /dev/null
+++ b/aleksis/apps/chronos/frontend/components/AmendLesson.vue
@@ -0,0 +1,187 @@
+<template>
+  <v-card-actions v-if="checkPermission('chronos.edit_substitution_rule')">
+    <edit-button
+      i18n-key="chronos.event.amend.edit_button"
+      @click="edit = true"
+      />
+    <delete-button
+      v-if="selectedEvent.meta.amended"
+      i18n-key="chronos.event.amend.delete_button"
+      @click="delete = true"
+      />
+    <dialog-object-form
+      v-model="edit"
+      :fields="fields"
+      :is-create="!selectedEvent.meta.amended"
+      createItemI18nKey="chronos.event.amend.title"
+      :gql-create-mutation="gqlCreateMutation"
+      :get-create-data="transformCreateData"
+      :default-item="default"
+      editItemI18nKey="chronos.event.amend.title"
+      :gql-patch-mutation="gqlPatchMutation"
+      :get-patch-data="transformPatchData"
+      :edit-item="initPatchData"
+      @cancel="open = false"
+      @save="updateOnSave()"
+      >
+      <template #subject.field="{ attrs, on, item }">
+        <v-autocomplete
+          :disabled="item.cancelled"
+          :items="amendableSubjects"
+          item-text="name"
+          item-value="id"
+          v-bind="attrs"
+          v-on="on"
+          />
+      </template>
+      <template #teachers.field="{ attrs, on, item }">
+        <v-autocomplete
+          :disabled="item.cancelled"
+          multiple
+          :items="amendableTeachers"
+          item-text="fullName"
+          item-value="id"
+          v-bind="attrs"
+          v-on="on"
+          chips
+          deletable-chips
+          />
+      </template>
+      <template #rooms.field="{ attrs, on, item }">
+        <v-autocomplete
+          :disabled="item.cancelled"
+          multiple
+          :items="amendableRooms"
+          item-text="name"
+          item-value="id"
+          v-bind="attrs"
+          v-on="on"
+          chips
+          deletable-chips
+          />
+      </template>
+      <template #cancelled.field="{ attrs, on }">
+        <v-checkbox v-bind="attrs" v-on="on" />
+      </template>
+      <template #comment.field="{ attrs, on }">
+        <v-textarea v-bind="attrs" v-on="on" />
+      </template>
+    </dialog-object-form>
+    <delete-dialog
+      deleteSuccessMessageI18nKey="chronos.event.amend.delete_success"
+      :gql-mutation="gqlDeleteMutation"
+      v-model="delete"
+      :item="selectedEvent.meta"
+      @success="updateOnSave()"
+      >
+      <template #title>
+        {{ $t("chronos.event.amend.delete_dialog") }}
+      </template>
+    </delete-dialog>
+  </v-card-actions>
+</template>
+
+<script>
+import permissionsMixin from "aleksis.core/mixins/permissions.js";
+import EditButton from "aleksis.core/components/generic/buttons/EditButton.vue";
+import DialogObjectForm from "aleksis.core/components/generic/dialogs/DialogObjectForm.vue";
+import DeleteButton from "aleksis.core/components/generic/buttons/DeleteButton.vue";
+import DeleteDialog from "aleksis.core/components/generic/dialogs/DeleteDialog.vue";
+import {
+  gqlSubjects,
+  gqlPersons,
+  gqlRooms,
+  createAmendLesson,
+  patchAmendLesson,
+  deleteAmendLesson,
+} from "./amendLesson.graphql";
+
+export default {
+  name: "AmendLesson",
+  components: {
+    EditButton,
+    DialogObjectForm,
+    DeleteButton,
+    DeleteDialog,
+  },
+  mixins: [permissionsMixin],
+  data() {
+    return {
+      edit: false,
+      fields: [
+        {
+          text: this.$t("chronos.event.amend.subject"),
+          value: "subject",
+        },
+        {
+          text: this.$t("chronos.event.amend.teachers"),
+          value: "teachers",
+        },
+        {
+          text: this.$t("chronos.event.amend.rooms"),
+          value: "rooms",
+        },
+        {
+          text: this.$t("chronos.event.amend.cancelled"),
+          value: "cancelled",
+        },
+        {
+          text: this.$t("chronos.event.amend.comment"),
+          value: "comment",
+        },
+      ],
+      default: {
+        cancelled: this.selectedEvent.meta.cancelled,
+        comment: this.selectedEvent.meta.comment,
+      },
+      gqlCreateMutation: createAmendLesson,
+      gqlPatchMutation: patchAmendLesson,
+      delete: false,
+      gqlDeleteMutation: deleteAmendLesson,
+    };
+  },
+  methods: {
+    transformCreateData(item) {
+      return {
+        ...item,
+        amends: this.selectedEvent.meta.id,
+        datetimeStart: this.selectedEvent.startDateTime.toUTC().toISO(),
+        datetimeEnd: this.selectedEvent.endDateTime.toUTC().toISO(),
+      };
+    },
+    transformPatchData(item) {
+      let { id, __typename, cancelled, ...patchItem } = item;
+      return {
+        ...patchItem,
+        // Normalize cancelled, v-checkbox returns null & does not
+        // honor false-value.
+        cancelled: cancelled ? true : false,
+      };
+    },
+    updateOnSave() {
+      this.$emit('refreshCalendar');
+      this.model = false;
+    },
+  },
+  computed: {
+    initPatchData() {
+      return {
+        id: this.selectedEvent.meta.id,
+        subject: this.selectedEvent.meta.subject?.id.toString(),
+        teachers: this.selectedEvent.meta.teachers.map((teacher) => teacher.id.toString()),
+        rooms: this.selectedEvent.meta.rooms.map((room) => room.id.toString()),
+        cancelled: this.selectedEvent.meta.cancelled,
+        comment: this.selectedEvent.meta.comment,
+      };
+    },
+  },
+  apollo: {
+    amendableSubjects: gqlSubjects,
+    amendableTeachers: gqlPersons,
+    amendableRooms: gqlRooms,
+  },
+  mounted() {
+    this.addPermissions(["chronos.edit_substitution_rule"]);
+  },
+};
+</script>
diff --git a/aleksis/apps/chronos/frontend/components/Timetable.vue b/aleksis/apps/chronos/frontend/components/Timetable.vue
index 6cd8e875adf52c96bc8062c4e1ed0001480ef16b..d685684be91e9e63b7c1e2dc0e991ee7b098b7cf 100644
--- a/aleksis/apps/chronos/frontend/components/Timetable.vue
+++ b/aleksis/apps/chronos/frontend/components/Timetable.vue
@@ -10,6 +10,21 @@ export default {
   apollo: {
     availableTimetables: {
       query: gqlAvailableTimetables,
+      result() {
+        if (
+          !this.selected &&
+          this.$route.params.id &&
+          this.$route.params.type
+        ) {
+          this.selectTimetable(
+            this.availableTimetables.find(
+              (t) =>
+                t.objId === this.$route.params.id &&
+                t.type.toLowerCase() === this.$route.params.type
+            )
+          );
+        }
+      },
     },
   },
   data() {
@@ -29,7 +44,7 @@ export default {
         this.$router.push({ name: "chronos.timetable" });
       } else if (
         selected.objId !== this.$route.params.id ||
-        selected.type !== this.$route.params.type
+        selected.type.toLowerCase() !== this.$route.params.type
       ) {
         this.$router.push({
           name: "chronos.timetableWithId",
diff --git a/aleksis/apps/chronos/frontend/components/amendLesson.graphql b/aleksis/apps/chronos/frontend/components/amendLesson.graphql
index bf6d16e4820b1f31da4b33a28660ad7036287d33..a93e89186df05efdfa77473b7f1a1751eb614c24 100644
--- a/aleksis/apps/chronos/frontend/components/amendLesson.graphql
+++ b/aleksis/apps/chronos/frontend/components/amendLesson.graphql
@@ -67,3 +67,9 @@ mutation patchAmendLesson($input: PatchLessonEventInput!, $id: ID!) {
     }
   }
 }
+
+mutation deleteAmendLesson($id: ID!) {
+  deleteAmendLesson(id: $id) {
+    ok
+  }
+}
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 2ef03c095e4e46a10fc52c9cc67a0e126a3a1d2e..c8df491e7f6c182785f91103f9c08c6382788a7e 100644
--- a/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue
+++ b/aleksis/apps/chronos/frontend/components/calendar_feeds/details/LessonDetails.vue
@@ -2,7 +2,8 @@
   <base-calendar-feed-details
     v-bind="$props"
     :color="currentSubject ? currentSubject.colour_bg : null"
-  >
+    without-location
+      >
     <template #title>
       <div
         :style="{
@@ -95,94 +96,23 @@
           </v-list-item-title>
         </v-list-item-content>
       </v-list-item>
-      <v-card-actions v-if="checkPermission('chronos.edit_substitution_rule')">
-        <edit-button
-          i18n-key="chronos.event.amend.button"
-          @click="amendEvent.open = true"
-        />
-        <dialog-object-form
-          v-model="amendEvent.open"
-          :fields="amendEvent.fields"
-          :is-create="!selectedEvent.meta.amended"
-          createItemI18nKey="chronos.event.amend.title"
-          :gql-create-mutation="amendEvent.gqlCreateMutation"
-          :get-create-data="transformCreateData"
-          :default-item="amendEvent.default"
-          editItemI18nKey="chronos.event.amend.title"
-          :gql-patch-mutation="amendEvent.gqlPatchMutation"
-          :get-patch-data="transformPatchData"
-          :edit-item="initPatchData"
-          @cancel="amendEvent.open = false"
-          @save="onAmendSave()"
-        >
-          <template #subject.field="{ attrs, on, item }">
-            <v-autocomplete
-              :disabled="item.cancelled"
-              :items="amendableSubjects"
-              item-text="name"
-              item-value="id"
-              v-bind="attrs"
-              v-on="on"
-            />
-          </template>
-          <template #teachers.field="{ attrs, on, item }">
-            <v-autocomplete
-              :disabled="item.cancelled"
-              multiple
-              :items="amendableTeachers"
-              item-text="fullName"
-              item-value="id"
-              v-bind="attrs"
-              v-on="on"
-              chips
-              deletable-chips
-            />
-          </template>
-          <template #rooms.field="{ attrs, on, item }">
-            <v-autocomplete
-              :disabled="item.cancelled"
-              multiple
-              :items="amendableRooms"
-              item-text="name"
-              item-value="id"
-              v-bind="attrs"
-              v-on="on"
-              chips
-              deletable-chips
-            />
-          </template>
-          <template #cancelled.field="{ attrs, on }">
-            <v-checkbox v-bind="attrs" v-on="on" />
-          </template>
-          <template #comment.field="{ attrs, on }">
-            <v-textarea v-bind="attrs" v-on="on" />
-          </template>
-        </dialog-object-form>
-      </v-card-actions>
+      <amend-lesson />
     </template>
   </base-calendar-feed-details>
 </template>
 
 <script>
-import permissionsMixin from "aleksis.core/mixins/permissions.js";
 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 EditButton from "aleksis.core/components/generic/buttons/EditButton.vue";
-import DialogObjectForm from "aleksis.core/components/generic/dialogs/DialogObjectForm.vue";
 
 import LessonRelatedObjectChip from "../../LessonRelatedObjectChip.vue";
 
 import lessonEvent from "../mixins/lessonEvent";
 import LessonEventSubject from "../../LessonEventSubject.vue";
-import {
-  gqlSubjects,
-  gqlPersons,
-  gqlRooms,
-  createAmendLesson,
-  patchAmendLesson,
-} from "../../amendLesson.graphql";
+
+import AmendLesson from "../../AmendLesson.vue";
 
 export default {
   name: "LessonDetails",
@@ -192,88 +122,8 @@ export default {
     BaseCalendarFeedDetails,
     CalendarStatusChip,
     CancelledCalendarStatusChip,
-    EditButton,
-    DialogObjectForm,
-  },
-  mixins: [permissionsMixin, calendarFeedDetailsMixin, lessonEvent],
-  data() {
-    return {
-      amendEvent: {
-        open: false,
-        fields: [
-          {
-            text: this.$t("chronos.event.amend.subject"),
-            value: "subject",
-          },
-          {
-            text: this.$t("chronos.event.amend.teachers"),
-            value: "teachers",
-          },
-          {
-            text: this.$t("chronos.event.amend.rooms"),
-            value: "rooms",
-          },
-          {
-            text: this.$t("chronos.event.amend.cancelled"),
-            value: "cancelled",
-          },
-          {
-            text: this.$t("chronos.event.amend.comment"),
-            value: "comment",
-          },
-        ],
-        default: {
-          cancelled: this.selectedEvent.meta.cancelled,
-          comment: this.selectedEvent.meta.comment,
-        },
-        gqlCreateMutation: createAmendLesson,
-        gqlPatchMutation: patchAmendLesson,
-      },
-    };
-  },
-  methods: {
-    transformCreateData(item) {
-      return {
-        ...item,
-        amends: this.selectedEvent.meta.id,
-        // LessonEvent has datetime in UTC & graphql does not like the Z timezone info
-        datetimeStart: this.selectedEvent.start.toISOString().replace("Z", ""),
-        datetimeEnd: this.selectedEvent.end.toISOString().replace("Z", ""),
-      };
-    },
-    transformPatchData(item) {
-      let { id, __typename, cancelled, ...patchItem } = item;
-      return {
-        ...patchItem,
-        // Normalize cancelled, v-checkbox returns null & does not
-        // honor false-value.
-        cancelled: cancelled ? true : false,
-      };
-    },
-    onAmendSave() {
-      this.$emit('refreshCalendar');
-      this.model = false;
-    },
-  },
-  computed: {
-    initPatchData() {
-      return {
-        id: this.selectedEvent.meta.id,
-        subject: this.selectedEvent.meta.subject?.id.toString(),
-        teachers: this.selectedEvent.meta.teachers.map((teacher) => teacher.id.toString()),
-        rooms: this.selectedEvent.meta.rooms.map((room) => room.id.toString()),
-        cancelled: this.selectedEvent.meta.cancelled,
-        comment: this.selectedEvent.meta.comment,
-      };
-    },
-  },
-  apollo: {
-    amendableSubjects: gqlSubjects,
-    amendableTeachers: gqlPersons,
-    amendableRooms: gqlRooms,
-  },
-  mounted() {
-    this.addPermissions(["chronos.edit_substitution_rule"]);
+    AmendLesson,
   },
+  mixins: [calendarFeedDetailsMixin, lessonEvent],
 };
 </script>
diff --git a/aleksis/apps/chronos/frontend/index.js b/aleksis/apps/chronos/frontend/index.js
index 3727ed27f35735198c26699771cf17809093a8b6..30451f93c2f0dfcb769a4ab92385b50fe1bfe61c 100644
--- a/aleksis/apps/chronos/frontend/index.js
+++ b/aleksis/apps/chronos/frontend/index.js
@@ -20,13 +20,16 @@ export default {
         inMenu: true,
         titleKey: "chronos.timetable.menu_title",
         icon: "mdi-grid",
-        permission: "chronos.view_timetables_rule",
+        permission: "chronos.view_timetable_overview_rule",
       },
     },
     {
       path: "timetable/:type/:id/",
       component: Timetable,
       name: "chronos.timetableWithId",
+      meta: {
+        permission: "chronos.view_timetable_overview_rule",
+      },
     },
   ],
 };
diff --git a/aleksis/apps/chronos/frontend/messages/en.json b/aleksis/apps/chronos/frontend/messages/en.json
index 90f35ab79ad1d6a5173b866a17b350dff9a68a29..b995b749a1677cdfbdbfef9888f4bd427062717c 100644
--- a/aleksis/apps/chronos/frontend/messages/en.json
+++ b/aleksis/apps/chronos/frontend/messages/en.json
@@ -28,7 +28,10 @@
       "no_room": "No room",
       "current_changes": "Current changes",
       "amend": {
-        "button": "Change",
+        "edit_button": "Change",
+        "delete_button": "Reset",
+        "delete_dialog": " Are you sure you want to delete this substitution?",
+        "delete_success": "The substitution was deleted successfully.",
         "title": "Change lesson",
         "subject": "Subject",
         "teachers": "Teachers",
diff --git a/aleksis/apps/chronos/menus.py b/aleksis/apps/chronos/menus.py
deleted file mode 100644
index 810e88c6d75a4cefb95210234fb70d690bb32ea1..0000000000000000000000000000000000000000
--- a/aleksis/apps/chronos/menus.py
+++ /dev/null
@@ -1,73 +0,0 @@
-from django.utils.translation import gettext_lazy as _
-
-MENUS = {
-    "NAV_MENU_CORE": [
-        {
-            "name": _("Timetables"),
-            "url": "#",
-            "svg_icon": "mdi:school-outline",
-            "root": True,
-            "validators": [
-                "menu_generator.validators.is_authenticated",
-                "aleksis.core.util.core_helpers.has_person",
-            ],
-            "submenu": [
-                {
-                    "name": _("My timetable"),
-                    "url": "my_timetable",
-                    "svg_icon": "mdi:account-outline",
-                    "validators": [
-                        (
-                            "aleksis.core.util.predicates.permission_validator",
-                            "chronos.view_my_timetable_rule",
-                        ),
-                    ],
-                },
-                {
-                    "name": _("All timetables"),
-                    "url": "all_timetables",
-                    "svg_icon": "mdi:grid",
-                    "validators": [
-                        (
-                            "aleksis.core.util.predicates.permission_validator",
-                            "chronos.view_timetable_overview_rule",
-                        ),
-                    ],
-                },
-                {
-                    "name": _("Daily lessons"),
-                    "url": "lessons_day",
-                    "svg_icon": "mdi:calendar-outline",
-                    "validators": [
-                        (
-                            "aleksis.core.util.predicates.permission_validator",
-                            "chronos.view_lessons_day_rule",
-                        ),
-                    ],
-                },
-                {
-                    "name": _("Daily supervisions"),
-                    "url": "supervisions_day",
-                    "svg_icon": "mdi:calendar-outline",
-                    "validators": [
-                        (
-                            "aleksis.core.util.predicates.permission_validator",
-                            "chronos.view_supervisions_day_rule",
-                        ),
-                    ],
-                },
-                {
-                    "name": _("Substitutions"),
-                    "url": "substitutions",
-                    "svg_icon": "mdi:update",
-                    "validators": [
-                        (
-                            "aleksis.core.util.predicates.permission_validator",
-                            "chronos.view_substitutions_rule",
-                        ),
-                    ],
-                },
-            ],
-        }
-    ]
-}
diff --git a/aleksis/apps/chronos/schema/__init__.py b/aleksis/apps/chronos/schema/__init__.py
index 4abeaef132e5bec552c53e1fa385f47205f467e3..f7cc25ff46c7fe7018876cc782fb6ad4e92e4eca 100644
--- a/aleksis/apps/chronos/schema/__init__.py
+++ b/aleksis/apps/chronos/schema/__init__.py
@@ -5,6 +5,7 @@ from graphene_django import DjangoObjectType
 from graphene_django_cud.mutations import DjangoCreateMutation, DjangoPatchMutation
 
 from aleksis.core.models import CalendarEvent, Group, Person, Room
+from aleksis.core.schema.base import DeleteMutation
 
 from ..models import LessonEvent
 from ..util.chronos_helpers import get_classes, get_rooms, get_teachers
@@ -57,21 +58,14 @@ class LessonEventType(DjangoObjectType):
         )
 
 
-class AmendLessonCreateMutation(DjangoCreateMutation):
-    class Meta:
-        model = LessonEvent
-        permissions = ("chronos.edit_substitution_rule",)
-        only_fields = (
-            "amends",
-            "datetime_start",
-            "datetime_end",
-            "subject",
-            "teachers",
-            "groups",
-            "rooms",
-            "cancelled",
-            "comment",
-        )
+class DatetimeTimezoneMixin:
+    """Handle datetimes for mutations with CalendarEvent objects.
+
+    This is necessary because the client sends timezone information as
+    ISO string which only includes an offset (+00:00 UTC) and an
+    offset is not a valid timezone. Instead we set UTC as timezone
+    here directly.
+    """
 
     @classmethod
     def handle_datetime_start(cls, value, name, info) -> int:
@@ -84,31 +78,45 @@ class AmendLessonCreateMutation(DjangoCreateMutation):
         return value
 
     @classmethod
-    def before_save(cls, root, info, input, obj):
+    def before_save(cls, root, info, input, obj, patch_obj=False):
+        # before_save has different signatures for different mutations
+        # This handles create & patch
+        # https://graphene-django-cud.readthedocs.io/en/latest/guide/other-hooks.html?highlight=before_save#before-save
+
+        if patch_obj:
+            obj = patch_obj
+            
         obj.timezone = obj.amends.timezone
         return obj
 
 
-class AmendLessonPatchMutation(DjangoPatchMutation):
+class AmendLessonCreateMutation(DatetimeTimezoneMixin, DjangoCreateMutation):
     class Meta:
         model = LessonEvent
         permissions = ("chronos.edit_substitution_rule",)
-        only_fields = ("subject", "teachers", "groups", "rooms", "cancelled", "comment")
+        only_fields = (
+            "amends",
+            "datetime_start",
+            "datetime_end",
+            "subject",
+            "teachers",
+            "groups",
+            "rooms",
+            "cancelled",
+            "comment",
+        )
 
-    @classmethod
-    def handle_datetime_start(cls, value, name, info) -> int:
-        value = value.replace(tzinfo=timezone.utc)
-        return value
 
-    @classmethod
-    def handle_datetime_end(cls, value, name, info) -> int:
-        value = value.replace(tzinfo=timezone.utc)
-        return value
+class AmendLessonPatchMutation(DatetimeTimezoneMixin, DjangoPatchMutation):
+    class Meta:
+        model = LessonEvent
+        permissions = ("chronos.edit_substitution_rule",)
+        only_fields = ("subject", "teachers", "groups", "rooms", "cancelled", "comment")
 
-    @classmethod
-    def before_save(cls, root, info, input, id, obj):
-        obj.timezone = obj.amends.timezone
-        return obj
+
+class AmendLessonDeleteMutation(DeleteMutation):
+    klass = LessonEvent
+    permission_required = "chronos.edit_substitution_rule"
 
 
 class TimetableType(graphene.Enum):
@@ -182,3 +190,4 @@ class Query(graphene.ObjectType):
 class Mutation(graphene.ObjectType):
     create_amend_lesson = AmendLessonCreateMutation.Field()
     patch_amend_lesson = AmendLessonPatchMutation.Field()
+    delete_amend_lesson = AmendLessonDeleteMutation.Field()