diff --git a/aleksis/apps/lesrooster/frontend/components/timetable_management/TimetableManagement.vue b/aleksis/apps/lesrooster/frontend/components/timetable_management/TimetableManagement.vue
index 12b149fb9a710d30361a16b0cf27b742666f0944..81b14747d745025ad65c7584fbafb7aad3d00ed2 100644
--- a/aleksis/apps/lesrooster/frontend/components/timetable_management/TimetableManagement.vue
+++ b/aleksis/apps/lesrooster/frontend/components/timetable_management/TimetableManagement.vue
@@ -22,8 +22,8 @@ import SubjectField from "aleksis.apps.cursus/components/SubjectField.vue";
 import BundleCard from "./BundleCard.vue";
 
 import { RRule } from "rrule";
-import TeacherTimeTable from "./timetables/TeacherTimeTable.vue";
-import RoomTimeTable from "./timetables/RoomTimeTable.vue";
+import TeacherTimeTable from "../timetables/TeacherTimeTable.vue";
+import RoomTimeTable from "../timetables/RoomTimeTable.vue";
 import LessonRatioChip from "./LessonRatioChip.vue";
 import TimeGridField from "../validity_range/TimeGridField.vue";
 import BlockingCard from "./BlockingCard.vue";
@@ -1200,13 +1200,13 @@ export default defineComponent({
             >
               <teacher-time-table
                 v-if="internalTimeGrid && selectedObjectType === 'teacher'"
-                :teacher-id="selectedObject"
+                :id="selectedObject"
                 :time-grid="timeGrid"
                 class="fill-height"
               />
               <room-time-table
                 v-if="internalTimeGrid && selectedObjectType === 'room'"
-                :room-id="selectedObject"
+                :id="selectedObject"
                 :time-grid="timeGrid"
                 class="fill-height"
               />
diff --git a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/MiniTimeTable.vue b/aleksis/apps/lesrooster/frontend/components/timetables/MiniTimeTable.vue
similarity index 91%
rename from aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/MiniTimeTable.vue
rename to aleksis/apps/lesrooster/frontend/components/timetables/MiniTimeTable.vue
index f32e518e2d6a4c714640ab3e3eec95410a0fb000..a4d71574a7222e2b791648ae2758ebeedb488a41 100644
--- a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/MiniTimeTable.vue
+++ b/aleksis/apps/lesrooster/frontend/components/timetables/MiniTimeTable.vue
@@ -1,7 +1,7 @@
 <script>
 import { defineComponent } from "vue";
-import { slots } from "../../breaks_and_slots/slot.graphql";
-import LessonCard from "../LessonCard.vue";
+import { slots } from "../breaks_and_slots/slot.graphql";
+import LessonCard from "../timetable_management/LessonCard.vue";
 import MessageBox from "aleksis.core/components/generic/MessageBox.vue";
 
 export default defineComponent({
@@ -93,6 +93,9 @@ export default defineComponent({
 
       return weekdayPeriodSlots;
     },
+    loading() {
+      return false;
+    },
   },
   methods: {
     styleForWeekdayAndPeriod(weekday, period) {
@@ -105,7 +108,14 @@ export default defineComponent({
 </script>
 
 <template>
-  <div class="timetable">
+  <div v-if="loading" class="d-flex justify-center pa-10">
+    <v-progress-circular
+      indeterminate
+      color="primary"
+      :size="50"
+    ></v-progress-circular>
+  </div>
+  <div v-else class="timetable">
     <!-- Empty div to fill top-left corner -->
     <div></div>
     <v-card
diff --git a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/RoomTimeTable.vue b/aleksis/apps/lesrooster/frontend/components/timetables/RoomTimeTable.vue
similarity index 84%
rename from aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/RoomTimeTable.vue
rename to aleksis/apps/lesrooster/frontend/components/timetables/RoomTimeTable.vue
index a50154bbbf49f681223283176652128fa08f4c8e..a667de14404263982534c728e3777ca192edea59 100644
--- a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/RoomTimeTable.vue
+++ b/aleksis/apps/lesrooster/frontend/components/timetables/RoomTimeTable.vue
@@ -7,7 +7,7 @@ export default defineComponent({
   name: "RoomTimeTable",
   extends: MiniTimeTable,
   props: {
-    roomId: {
+    id: {
       type: String,
       required: true,
     },
@@ -16,6 +16,9 @@ export default defineComponent({
     lessons() {
       return this.lessonsRoom;
     },
+    loading() {
+      return this.$apollo.queries.lessonsRoom.loading;
+    },
   },
   apollo: {
     lessonsRoom: {
@@ -23,7 +26,7 @@ export default defineComponent({
       variables() {
         return {
           timeGrid: this.timeGrid.id,
-          room: this.roomId,
+          room: this.id,
         };
       },
       skip() {
diff --git a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/TeacherTimeTable.vue b/aleksis/apps/lesrooster/frontend/components/timetables/TeacherTimeTable.vue
similarity index 84%
rename from aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/TeacherTimeTable.vue
rename to aleksis/apps/lesrooster/frontend/components/timetables/TeacherTimeTable.vue
index 5ed3211176f9bb0ad66c654a5fe1c36747ff13b0..f8d89a4b564ac00126e72db72e29a36637b5423c 100644
--- a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/TeacherTimeTable.vue
+++ b/aleksis/apps/lesrooster/frontend/components/timetables/TeacherTimeTable.vue
@@ -7,7 +7,7 @@ export default defineComponent({
   name: "TeacherTimeTable",
   extends: MiniTimeTable,
   props: {
-    teacherId: {
+    id: {
       type: String,
       required: true,
     },
@@ -16,6 +16,9 @@ export default defineComponent({
     lessons() {
       return this.lessonsTeacher;
     },
+    loading() {
+      return this.$apollo.queries.lessonsTeacher.loading;
+    },
   },
   apollo: {
     lessonsTeacher: {
@@ -23,7 +26,7 @@ export default defineComponent({
       variables() {
         return {
           timeGrid: this.timeGrid.id,
-          teacher: this.teacherId,
+          teacher: this.id,
         };
       },
       skip() {
diff --git a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/timetables.graphql b/aleksis/apps/lesrooster/frontend/components/timetables/timetables.graphql
similarity index 67%
rename from aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/timetables.graphql
rename to aleksis/apps/lesrooster/frontend/components/timetables/timetables.graphql
index 9bbcc2eb5a3aeaea2c5210acc1b3a59f85bad9ba..8e8a735ace05dadd21764b6fdf329659ca641b84 100644
--- a/aleksis/apps/lesrooster/frontend/components/timetable_management/timetables/timetables.graphql
+++ b/aleksis/apps/lesrooster/frontend/components/timetables/timetables.graphql
@@ -111,3 +111,58 @@ query lessonsRoom($room: ID!, $timeGrid: ID!) {
     canDelete
   }
 }
+
+query lessonsGroup($group: ID!, $timeGrid: ID!) {
+  lessonsGroup: lessonObjectsForGroup(group: $group, timeGrid: $timeGrid) {
+    id
+    slotStart {
+      id
+      period
+      weekday
+    }
+    slotEnd {
+      id
+      period
+      weekday
+    }
+    subject {
+      id
+      name
+      colourFg
+      colourBg
+    }
+    teachers {
+      id
+      fullName
+      shortName
+    }
+    rooms {
+      id
+      name
+      shortName
+    }
+    course {
+      id
+      name
+      subject {
+        id
+        name
+        colourFg
+        colourBg
+      }
+      teachers {
+        id
+        fullName
+        shortName
+      }
+      groups {
+        id
+        name
+        shortName
+      }
+    }
+    recurrence
+    canEdit
+    canDelete
+  }
+}