diff --git a/aleksis/core/frontend/components/availability_event/AvailabilityEventList.vue b/aleksis/core/frontend/components/availability_event/AvailabilityEventList.vue
index de80367f267677ac23d5454e0719d8df30cdf158..5d63ee410bf9a8a2a519841bc561155cfa0ab682 100644
--- a/aleksis/core/frontend/components/availability_event/AvailabilityEventList.vue
+++ b/aleksis/core/frontend/components/availability_event/AvailabilityEventList.vue
@@ -4,7 +4,7 @@ import DateTimeField from "../generic/forms/DateTimeField.vue";
 import DateField from "../generic/forms/DateField.vue";
 import CreateButton from "../generic/buttons/CreateButton.vue";
 
-import CalendarEventDialog from "../calendar/CalendarEventDialog.vue";
+import MainCalendarEventDialog from "../calendar/MainCalendarEventDialog.vue";
 </script>
 
 <template>
@@ -22,7 +22,7 @@ import CalendarEventDialog from "../calendar/CalendarEventDialog.vue";
     ref="list"
   >
     <template #createComponent="{ attrs, on, createMode, editItem }">
-      <calendar-event-dialog
+      <main-calendar-event-dialog
         v-bind="attrs"
         v-on="on"
         :initial-selected-event="!editItem?.free ? 'freeEvent' : 'busyEvent'"
@@ -35,7 +35,7 @@ import CalendarEventDialog from "../calendar/CalendarEventDialog.vue";
             color="secondary"
           />
         </template>
-      </calendar-event-dialog>
+      </main-calendar-event-dialog>
     </template>
 
     <template #free="{ item }">
diff --git a/aleksis/core/frontend/components/calendar/CalendarEventDialog.vue b/aleksis/core/frontend/components/calendar/CalendarEventDialog.vue
index 658469dc06c45dd525a4caaa32a5a785a67c2ab6..45729786a080640b7ac0ce3dab32261e43fcc5dd 100644
--- a/aleksis/core/frontend/components/calendar/CalendarEventDialog.vue
+++ b/aleksis/core/frontend/components/calendar/CalendarEventDialog.vue
@@ -22,7 +22,7 @@ import GroupField from "../generic/forms/GroupField.vue";
     :fields="editableFields"
   >
     <template #activator="{ attrs, on }">
-      <slot name="activator" v-bind="{ attrs, on, events }" />
+      <slot name="activator" v-bind="{ attrs, on }" />
     </template>
 
     <template #title>
@@ -110,52 +110,13 @@ import GroupField from "../generic/forms/GroupField.vue";
       <v-textarea rows="1" auto-grow v-bind="attrs" v-on="on" />
     </template>
 
-    <!-- eslint-disable-next-line vue/valid-v-slot -->
-    <template #location.field="{ attrs, on }">
-      <v-slide-y-reverse-transition appear>
-        <v-text-field v-bind="attrs" v-on="on" />
-      </v-slide-y-reverse-transition>
-    </template>
-
-    <!-- eslint-disable-next-line vue/valid-v-slot -->
-    <template #persons.field="{ attrs, on }">
-      <v-slide-y-reverse-transition appear>
-        <person-field
-          v-if="checkPermission('core.create_personal_event_with_invitations_rule')"
-          multiple
-          v-bind="attrs"
-          v-on="on"
-        />
-      </v-slide-y-reverse-transition>
-    </template>
-
-    <!-- eslint-disable-next-line vue/valid-v-slot -->
-    <template #groups.field="{ attrs, on }">
-      <v-slide-y-reverse-transition appear>
-        <group-field
-          v-if="checkPermission('core.create_personal_event_with_invitations_rule')"
-          multiple
-          v-bind="attrs"
-          v-on="on"
-        />
-      </v-slide-y-reverse-transition>
+    <template v-for="(_, slot) of $scopedSlots" #[slot]="scope">
+      <slot :name="slot" v-bind="scope" />
     </template>
   </dialog-object-form>
 </template>
 
 <script>
-import {
-  createPersonalEvents,
-  updatePersonalEvents,
-} from "./personal_event/personalEvent.graphql";
-
-import {
-  createAvailabilityEvents,
-  updateAvailabilityEvents,
-} from "../availability_event/availabilityEvent.graphql";
-
-import permissionsMixin from "../../mixins/permissions.js";
-
 import { DateTime } from "luxon";
 
 export default {
@@ -204,52 +165,19 @@ export default {
           cols: 12,
         },
       },
-      events: {
-        personalEvent: {
-          textKey: "calendar.create_event.event_types.personal_event",
-          createMutation: createPersonalEvents,
-          updateMutation: updatePersonalEvents,
-          fields: {
-            location: {
-              default: undefined,
-              cols: 12,
-              textKey: "calendar.create_event.personal_events.location"
-            },
-            persons: {
-              default: [],
-              cols: 6,
-              textKey: "calendar.create_event.personal_events.persons"
-            },
-            groups: {
-              default: [],
-              cols: 6,
-              textKey: "calendar.create_event.personal_events.groups"
-            },
-          },
-        },
-        freeEvent: {
-          textKey: "calendar.create_event.event_types.free_event",
-          createMutation: createAvailabilityEvents,
-          updateMutation: updateAvailabilityEvents,
-          fields: {},
-          filter: (object) => ({ ...object, free: true }),
-        },
-        busyEvent: {
-          textKey: "calendar.create_event.event_types.busy_event",
-          createMutation: createAvailabilityEvents,
-          updateMutation: updateAvailabilityEvents,
-          fields: {},
-          filter: (object) => ({ ...object, free: false }),
-        },
-      },
       selectedEvent: this.initialSelectedEvent,
     };
   },
   props: {
+    // TODO
+    events: {
+      type: Object,
+      required: false,
+      default: () => ({}),
+    },
     initialSelectedEvent: {
       type: String,
       required: false,
-      default: "personalEvent",
     },
     selectableEvents: {
       type: Array,
@@ -261,7 +189,6 @@ export default {
       default: undefined,
     },
   },
-  mixins: [permissionsMixin],
   methods: {
     camelToSnakeCase(str) {
         return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
@@ -311,7 +238,7 @@ export default {
     },
   },
   computed: {
-    // Needed since a props default can not access data
+    // Needed since a prop's default can not access data
     selectableEventsWithDefault() {
       return this.selectableEvents ? this.selectableEvents : Object.keys(this.events);
     },
@@ -342,12 +269,12 @@ export default {
       return Object.entries(this.fields).filter(([_, {hide}]) => !hide).map(this.formatField);
     },
   },
-  mounted() {
-    this.addPermissions(["core.create_personal_event_with_invitations_rule"]);
-  },
   watch: {
-    initialSelectedEvent: (newVal) => {
-      this.selectedEvent = newVal;
+    initialSelectedEvent: {
+      handler(newVal) {
+        this.selectedEvent = newVal;
+      },
+      deep: true,
     },
   },
 };
diff --git a/aleksis/core/frontend/components/calendar/CalendarOverview.vue b/aleksis/core/frontend/components/calendar/CalendarOverview.vue
index 1767f16483b1423af6f627db25ea6de04e67cb7a..847839a89d14056e480aa4b81044b21e8d908321 100644
--- a/aleksis/core/frontend/components/calendar/CalendarOverview.vue
+++ b/aleksis/core/frontend/components/calendar/CalendarOverview.vue
@@ -1,6 +1,6 @@
 <template>
   <v-sheet class="mb-10">
-    <calendar-event-dialog
+    <main-calendar-event-dialog
       :initial-selected-event="presetEvent"
       @save="$refs.calendar.refresh()"
     >
@@ -37,7 +37,7 @@
           </v-chip>
         </v-speed-dial>
       </template>
-    </calendar-event-dialog>
+    </main-calendar-event-dialog>
     <v-row align="stretch" class="page-height flex-nowrap">
       <v-navigation-drawer
         :clipped="$vuetify.breakpoint.lgAndUp"
@@ -143,7 +143,7 @@ import CalendarControlBar from "./CalendarControlBar.vue";
 import CalendarTypeSelect from "./CalendarTypeSelect.vue";
 import Calendar from "./Calendar.vue";
 import CalendarDownloadAllButton from "./CalendarDownloadAllButton.vue";
-import CalendarEventDialog from "./CalendarEventDialog.vue";
+import MainCalendarEventDialog from "./MainCalendarEventDialog.vue";
 import calendarMixin from "./calendarMixin";
 import calendarSelectedFeedsMixin from "./calendarSelectedFeedsMixin";
 
@@ -158,7 +158,7 @@ export default {
     CalendarControlBar,
     CalendarSelect,
     CalendarDownloadAllButton,
-    CalendarEventDialog,
+    MainCalendarEventDialog,
     CreateButton,
   },
   methods: {
diff --git a/aleksis/core/frontend/components/calendar/MainCalendarEventDialog.vue b/aleksis/core/frontend/components/calendar/MainCalendarEventDialog.vue
new file mode 100644
index 0000000000000000000000000000000000000000..e02c8da01d14129d633ccf1e36f164199fcd420d
--- /dev/null
+++ b/aleksis/core/frontend/components/calendar/MainCalendarEventDialog.vue
@@ -0,0 +1,113 @@
+<script setup>
+import CalendarEventDialog from "./CalendarEventDialog.vue";
+import PersonField from "../generic/forms/PersonField.vue";
+import GroupField from "../generic/forms/GroupField.vue";
+</script>
+
+<template>
+  <calendar-event-dialog
+    v-bind="$attrs"
+    v-on="$listeners"
+    :events="events"
+  > 
+    <template #activator="{ attrs, on }">
+      <slot name="activator" v-bind="{ attrs, on, events }" />
+    </template>
+
+    <!-- eslint-disable-next-line vue/valid-v-slot -->
+    <template #location.field="{ attrs, on }">
+      <v-slide-y-reverse-transition appear>
+        <v-text-field v-bind="attrs" v-on="on" />
+      </v-slide-y-reverse-transition>
+    </template>
+
+    <!-- eslint-disable-next-line vue/valid-v-slot -->
+    <template #persons.field="{ attrs, on }">
+      <v-slide-y-reverse-transition appear>
+        <person-field
+          v-if="checkPermission('core.create_personal_event_with_invitations_rule')"
+          multiple
+          v-bind="attrs"
+          v-on="on"
+        />
+      </v-slide-y-reverse-transition>
+    </template>
+
+    <!-- eslint-disable-next-line vue/valid-v-slot -->
+    <template #groups.field="{ attrs, on }">
+      <v-slide-y-reverse-transition appear>
+        <group-field
+          v-if="checkPermission('core.create_personal_event_with_invitations_rule')"
+          multiple
+          v-bind="attrs"
+          v-on="on"
+        />
+      </v-slide-y-reverse-transition>
+    </template>
+  </calendar-event-dialog>
+</template>
+
+<script>
+import {
+  createPersonalEvents,
+  updatePersonalEvents,
+} from "./personal_event/personalEvent.graphql";
+
+import {
+  createAvailabilityEvents,
+  updateAvailabilityEvents,
+} from "../availability_event/availabilityEvent.graphql";
+
+import permissionsMixin from "../../mixins/permissions.js";
+
+export default {
+  name: "MainCalendarEventDialog",
+  extends: "CalendarEventDialog",
+  mixins: [permissionsMixin],
+  data() {
+    return {
+      events: {
+        personalEvent: {
+          textKey: "calendar.create_event.event_types.personal_event",
+          createMutation: createPersonalEvents,
+          updateMutation: updatePersonalEvents,
+          fields: {
+            location: {
+              default: undefined,
+              cols: 12,
+              textKey: "calendar.create_event.personal_events.location"
+            },
+            persons: {
+              default: [],
+              cols: 6,
+              textKey: "calendar.create_event.personal_events.persons"
+            },
+            groups: {
+              default: [],
+              cols: 6,
+              textKey: "calendar.create_event.personal_events.groups"
+            },
+          },
+        },
+        freeEvent: {
+          textKey: "calendar.create_event.event_types.free_event",
+          createMutation: createAvailabilityEvents,
+          updateMutation: updateAvailabilityEvents,
+          fields: {},
+          filter: (object) => ({ ...object, free: true }),
+        },
+        busyEvent: {
+          textKey: "calendar.create_event.event_types.busy_event",
+          createMutation: createAvailabilityEvents,
+          updateMutation: updateAvailabilityEvents,
+          fields: {},
+          filter: (object) => ({ ...object, free: false }),
+        },
+      },
+    };
+  },
+  mounted() {
+    this.addPermissions(["core.create_personal_event_with_invitations_rule"]);
+  },
+};
+</script>
diff --git a/aleksis/core/frontend/components/calendar_feeds/details/AvailabilitiesDetails.vue b/aleksis/core/frontend/components/calendar_feeds/details/AvailabilitiesDetails.vue
index c860cd6d1c9e90b43874f03f94c7e40950bd8759..d7f12ff9722da8ff6c236e5b5bb83c9593cfb8d2 100644
--- a/aleksis/core/frontend/components/calendar_feeds/details/AvailabilitiesDetails.vue
+++ b/aleksis/core/frontend/components/calendar_feeds/details/AvailabilitiesDetails.vue
@@ -32,7 +32,7 @@
         <!--
             Dialog with button to edit the availability event.
           -->
-        <calendar-event-dialog
+        <main-calendar-event-dialog
           v-if="selectedEvent.meta.can_edit"
           :edit-item="initPatchData"
           :initial-selected-event="initPatchData.free ? 'freeEvent' : 'busyEvent'"
@@ -48,7 +48,7 @@
               outlined
             />
           </template>
-        </calendar-event-dialog>
+        </main-calendar-event-dialog>
 
         <!--
             Dialog with button to delete the availability event.
@@ -76,7 +76,7 @@
 import calendarFeedDetailsMixin from "../../../mixins/calendarFeedDetails.js";
 import BaseCalendarFeedDetails from "../../calendar/BaseCalendarFeedDetails.vue";
 
-import CalendarEventDialog from "../../calendar/CalendarEventDialog.vue";
+import MainCalendarEventDialog from "../../calendar/MainCalendarEventDialog.vue";
 import { deleteAvailabilityEvents } from "../../availability_event/availabilityEvent.graphql";
 
 import DeleteButton from "../../generic/buttons/DeleteButton.vue";
@@ -87,7 +87,7 @@ export default {
   name: "AvailabilitiesDetails",
   components: {
     BaseCalendarFeedDetails,
-    CalendarEventDialog,
+    MainCalendarEventDialog,
     DeleteButton,
     DeleteDialog,
     EditButton,
diff --git a/aleksis/core/frontend/components/calendar_feeds/details/PersonalDetails.vue b/aleksis/core/frontend/components/calendar_feeds/details/PersonalDetails.vue
index f7a520cf426b4756ad6a62f7698c36b61bc28b14..3c6d9ff9b8b379cdee7bdc2304ceefaa0579a7b8 100644
--- a/aleksis/core/frontend/components/calendar_feeds/details/PersonalDetails.vue
+++ b/aleksis/core/frontend/components/calendar_feeds/details/PersonalDetails.vue
@@ -89,7 +89,7 @@
         <!--
           Dialog with button to edit the personal event.
         -->
-        <calendar-event-dialog
+        <main-calendar-event-dialog
           v-if="selectedEvent.meta.can_edit"
           :edit-item="initPatchData"
           initial-selected-event="personalEvent"
@@ -105,7 +105,7 @@
               outlined
             />
           </template>
-        </calendar-event-dialog>
+        </main-calendar-event-dialog>
 
         <!--
           Dialog with button to delete the personal event.
@@ -133,7 +133,7 @@
 import calendarFeedDetailsMixin from "../../../mixins/calendarFeedDetails.js";
 import BaseCalendarFeedDetails from "../../calendar/BaseCalendarFeedDetails.vue";
 
-import CalendarEventDialog from "../../calendar/CalendarEventDialog.vue";
+import MainCalendarEventDialog from "../../calendar/MainCalendarEventDialog.vue";
 import { deletePersonalEvents } from "../../calendar/personal_event/personalEvent.graphql";
 
 import DeleteButton from "../../generic/buttons/DeleteButton.vue";
@@ -144,7 +144,7 @@ export default {
   name: "CustomDetails",
   components: {
     BaseCalendarFeedDetails,
-    CalendarEventDialog,
+    MainCalendarEventDialog,
     DeleteButton,
     DeleteDialog,
     EditButton,