diff --git a/resources/assets/stylesheets/scss/courseware/layouts/tree.scss b/resources/assets/stylesheets/scss/courseware/layouts/tree.scss
index 5f976a22a2a0ae5cda5fdcc60cc82c21c121ea7b..c74c4214b7024139a4e9c23bb659a403c9df1769 100644
--- a/resources/assets/stylesheets/scss/courseware/layouts/tree.scss
+++ b/resources/assets/stylesheets/scss/courseware/layouts/tree.scss
@@ -2,7 +2,6 @@
     ol {
         list-style: none;
         padding-left: 1.25em;
-        margin-bottom: 20px;
 
         &.cw-tree-root-list {
             padding-left: 0;
@@ -33,6 +32,10 @@
                             border-bottom: solid thin var(--content-color-40);
                             margin-bottom: 12px;
 
+                            > .cw-sortable-handle {
+                                margin-bottom: 2px;
+                            }
+
                             > a.cw-tree-item-link {
                                 display: inline-block;
                                 width: calc(100% - 4px);
@@ -48,8 +51,13 @@
                         ol {
                             padding-left: 0.25em;
 
+                            &.cw-tree-adder-list,
                             &.cw-tree-draggable-list {
-                                padding-left: 1em;
+                                padding-left: 2px;
+                            }
+                            &.cw-tree-adder-list {
+                                margin-left: 16px;
+                                height: 30px;
                             }
 
                             > li.cw-tree-item {
@@ -57,27 +65,36 @@
 
                                 > .cw-tree-item-wrapper {
                                     border: none;
+                                    line-height: 28px;
 
-                                    > a.cw-tree-item-link {
-                                        display: inline-block;
+                                    > a.cw-tree-item-link,
+                                    form {
                                         border-bottom: none;
                                         font-size: 14px;
                                         width: calc(100% - 20px);
                                         background-repeat: no-repeat;
+                                        background-position-y: center;
                                         padding-left: 18px;
                                         margin-left: 4px;
                                         margin-bottom: 0;
+                                        line-height: 28px;
 
                                         &.cw-tree-item-link-edit {
                                             width: calc(100% - 38px);
                                         }
 
                                         @include background-icon(bullet-dot, clickable, 18);
+                                    }
+                                    form {
+                                        display: inline;
+                                        background-position-y: center;
+                                    }
+                                    > a.cw-tree-item-link {
+                                        display: inline-block;
 
                                         &:hover {
                                             @include background-icon(bullet-dot, attention, 18);
                                         }
-
                                         &.cw-tree-item-link-current {
                                             @include background-icon(bullet-dot, info, 18);
                                         }
@@ -95,14 +112,44 @@
         }
     }
 
-    .cw-sortable-handle {
-        vertical-align: middle;
+    .cw-tree-item-wrapper {
+        .cw-sortable-handle {
+            vertical-align: middle;
+            opacity: 0;
+            &:focus {
+                opacity: 1;
+            }
+        }
+        &:hover {
+            .cw-sortable-handle {
+                opacity: 1;
+            }
+        }
     }
 
     .cw-tree-item-link {
+        .cw-tree-item-edit-button {
+            opacity: 0;
+            padding: 0 4px;
+            vertical-align: bottom;
+            border: none;
+            background-color: transparent;
+            cursor: pointer;
+            img {
+                vertical-align: middle;
+            }
+            &:focus {
+                opacity: 1;
+            }
+        }
+
         &:hover {
             background-color: var(--light-gray-color-20);
             color: var(--active-color);
+
+            .cw-tree-item-edit-button {
+                opacity: 1;
+            }
         }
 
         &.cw-tree-item-link-current {
@@ -122,10 +169,10 @@
 
         @each $type, $icon in $tree-item-flag-icons {
             .cw-tree-item-flag-#{$type} {
-                display: inline-block;
                 width: 16px;
                 height: 16px;
                 vertical-align: top;
+                float: right;
                 @include background-icon(#{$icon}, clickable, 16);
             }
 
@@ -159,5 +206,33 @@
 
     .cw-tree-item-ghost {
         opacity: 0.6;
+        border: dashed 2px var(--content-color-40);
+        height: 28px;
+        margin-left: 24px !important;
+
+        .cw-tree-item-wrapper {
+            visibility: hidden;
+        }
+    }
+
+    form.cw-tree-item-adder-form,
+    form.cw-tree-item-updater {
+        display: inline;
+
+        input {
+            height: 22px;
+        }
+
+        button {
+            min-width: unset;
+            height: 28px;
+            width: 28px;
+            padding: 0;
+            margin: -1px 0 0 0;
+
+            &::before {
+                margin: 4px;
+            }
+        }
     }
 }
diff --git a/resources/assets/stylesheets/scss/courseware/variables.scss b/resources/assets/stylesheets/scss/courseware/variables.scss
index af97f927b570ca9e37050bfb0bcc8584fbda6996..8ce915f3a209cdfacd51eb11dafc3a9225de2ee7 100644
--- a/resources/assets/stylesheets/scss/courseware/variables.scss
+++ b/resources/assets/stylesheets/scss/courseware/variables.scss
@@ -10,7 +10,7 @@ $element-icons: (
 
 $tree-item-flag-icons: (
     date: date,
-    write: edit,
+    write: community,
     cant-read: lock-locked2,
 );
 
diff --git a/resources/vue/components/courseware/structural-element/CoursewareTree.vue b/resources/vue/components/courseware/structural-element/CoursewareTree.vue
index 4103c1bbe5c7f5c13b3b2ce26b5d363c116c2344..68947e3998e5197a16e62190d869c4d45740518e 100644
--- a/resources/vue/components/courseware/structural-element/CoursewareTree.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareTree.vue
@@ -18,6 +18,7 @@
                 @moveItemNextLevel="moveItemNextLevel"
                 @childrenUpdated="updateNestedChildren"
             ></courseware-tree-item>
+            <courseware-tree-item-adder v-if="editMode && canEditRoot" :parentId="rootElement.id"/>
         </ol>
         <studip-progress-indicator
             v-else 
@@ -28,6 +29,7 @@
 
 <script>
 import CoursewareTreeItem from './CoursewareTreeItem.vue';
+import CoursewareTreeItemAdder from './CoursewareTreeItemAdder.vue';
 import StudipProgressIndicator from '../../StudipProgressIndicator.vue';
 
 import { mapActions, mapGetters } from 'vuex';
@@ -35,6 +37,7 @@ import { mapActions, mapGetters } from 'vuex';
 export default {
     components: { 
         CoursewareTreeItem,
+        CoursewareTreeItemAdder,
         StudipProgressIndicator
     },
     name: 'courseware-tree',
@@ -78,6 +81,9 @@ export default {
             }
 
         },
+        canEditRoot() {
+            return this.rootElement.attributes['can-edit'];
+        },
         editMode() {
             return this.viewMode === 'edit';
         },
diff --git a/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue b/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue
index 820b58a6f38f932caac442f0e30f05457fecc1ff..a4bfa35e48cc43cf2bdd3b55f230a7540be27996 100644
--- a/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue
+++ b/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue
@@ -1,8 +1,5 @@
 <template>
-    <li v-if="showItem"
-        :draggable="editMode ? true : null"
-        :aria-selected="editMode ? keyboardSelected : null"
-    >
+    <li v-if="showItem" :draggable="editMode ? true : null" :aria-selected="editMode ? keyboardSelected : null">
         <div class="cw-tree-item-wrapper">
             <span
                 v-if="editMode && depth > 0 && canEdit"
@@ -14,16 +11,27 @@
                 @keydown="handleKeyEvent"
             >
             </span>
+            <courseware-tree-item-updater
+                v-if="editMode && editingItem"
+                :structuralElement="element"
+                @close="editingItem = false"
+                @childrenUpdated="$emit('childrenUpdated')"
+            />
             <router-link
+                v-else
                 :to="'/structural_element/' + element.id"
                 class="cw-tree-item-link"
                 :class="{
                     'cw-tree-item-link-current': isCurrent,
                     'cw-tree-item-link-edit': editMode,
-                    'cw-tree-item-link-selected': keyboardSelected
+                    'cw-tree-item-link-selected': keyboardSelected,
                 }"
             >
-                {{ element.attributes?.title || "–" }}
+                {{ element.attributes?.title || '–' }}
+                <button v-if="editMode && canEdit" class="cw-tree-item-edit-button" @click.prevent="editingItem = true">
+                    <studip-icon shape="edit" />
+                </button>
+
                 <span v-if="task">| {{ solverName }}</span>
                 <span
                     v-if="hasReleaseOrWithdrawDate"
@@ -50,14 +58,11 @@
                     <span
                         v-else
                         class="cw-tree-item-sequential cw-tree-item-sequential-percentage"
-                        :title="$gettextInterpolate(
-                                    $gettext('Fortschritt: %{progress}%'),
-                                    {progress: itemProgress}
-                                )"
+                        :title="$gettextInterpolate($gettext('Fortschritt: %{progress}%'), { progress: itemProgress })"
                     >
                         {{ itemProgress }} %
                     </span>
-            </template>
+                </template>
             </router-link>
         </div>
         <ol
@@ -85,11 +90,11 @@
             handle=".cw-sortable-handle"
             v-bind="dragOptions"
             :elementId="element.id"
-            :list="nestedChildren" 
+            :list="nestedChildren"
             :group="{ name: 'g1' }"
             @end="endDrag"
         >
-            <courseware-tree-item 
+            <courseware-tree-item
                 v-for="el in nestedChildren"
                 :key="el.id"
                 :element="el"
@@ -108,17 +113,28 @@
                 @childrenUpdated="$emit('childrenUpdated')"
             />
         </draggable>
+        <ol
+            v-if="editMode && canEdit && isFirstLevel"
+            class="cw-tree-adder-list"
+        >
+            <courseware-tree-item-adder :parentId="element.id" />
+        </ol>
     </li>
 </template>
 
 <script>
+import CoursewareTreeItemAdder from './CoursewareTreeItemAdder.vue';
+import CoursewareTreeItemUpdater from './CoursewareTreeItemUpdater.vue';
 import draggable from 'vuedraggable';
+
 import { mapGetters, mapActions } from 'vuex';
 
 export default {
     name: 'courseware-tree-item',
     components: {
-        draggable
+        CoursewareTreeItemAdder,
+        CoursewareTreeItemUpdater,
+        draggable,
     },
     props: {
         element: {
@@ -134,22 +150,23 @@ export default {
         },
         keyboardSelectedProp: {
             type: Boolean,
-            default: false
+            default: false,
         },
         newPos: {
-            type: Number
+            type: Number,
         },
         newParentId: {
-            type: Number
+            type: Number,
         },
         siblingCount: {
-            type: Number
-        }
+            type: Number,
+        },
     },
     data() {
         return {
-            keyboardSelected: false
-        }
+            keyboardSelected: false,
+            editingItem: false,
+        };
     },
     computed: {
         ...mapGetters({
@@ -168,8 +185,10 @@ export default {
             return {
                 attrs: {
                     role: 'listbox',
-                    ['aria-label']: this.$gettextInterpolate(this.$gettext('Unterseiten von %{elementName}'),{ elementName: this.element.attributes?.title })
-                }
+                    ['aria-label']: this.$gettextInterpolate(this.$gettext('Unterseiten von %{elementName}'), {
+                        elementName: this.element.attributes?.title,
+                    }),
+                },
             };
         },
         children() {
@@ -179,7 +198,8 @@ export default {
 
             return this.childrenById(this.element.id)
                 .map((id) => this.structuralElementById({ id }))
-                .filter(Boolean).sort((a,b) => a.attributes.position - b.attributes.position);
+                .filter(Boolean)
+                .sort((a, b) => a.attributes.position - b.attributes.position);
         },
         nestedChildren() {
             return this.element.nestedChildren ?? [];
@@ -198,7 +218,8 @@ export default {
         },
         hasReleaseOrWithdrawDate() {
             return (
-                this.element.attributes?.['release-date'] !== null || this.element.attributes?.['withdraw-date'] !== null
+                this.element.attributes?.['release-date'] !== null ||
+                this.element.attributes?.['withdraw-date'] !== null
             );
         },
         hasWriteApproval() {
@@ -207,7 +228,10 @@ export default {
             if (!writeApproval || Object.keys(writeApproval).length === 0) {
                 return false;
             }
-            return (writeApproval.all || writeApproval.groups.length > 0 || writeApproval.users.length > 0) && this.element.attributes?.['can-edit'];
+            return (
+                (writeApproval.all || writeApproval.groups.length > 0 || writeApproval.users.length > 0) &&
+                this.element.attributes?.['can-edit']
+            );
         },
         hasNoReadApproval() {
             if (this.context.type === 'users') {
@@ -286,11 +310,11 @@ export default {
             return {
                 animation: 0,
                 disabled: false,
-                ghostClass: "cw-tree-item-ghost"
+                ghostClass: 'cw-tree-item-ghost',
             };
         },
         canEdit() {
-            return this.element.attributes['can-edit'];
+            return this.element.attributes?.['can-edit'] ?? false;
         },
         inCourse() {
             return this.context.type === 'courses';
@@ -308,12 +332,12 @@ export default {
     methods: {
         ...mapActions({
             loadTask: 'loadTask',
-            setAssistiveLiveContents: 'setAssistiveLiveContents'
+            setAssistiveLiveContents: 'setAssistiveLiveContents',
         }),
         endDrag(e) {
             let sortArray = [];
             for (let child of e.to.childNodes) {
-                sortArray.push({id: child.attributes.elementid.nodeValue, type: 'courseware-structural-elements'});
+                sortArray.push({ id: child.attributes.elementid.nodeValue, type: 'courseware-structural-elements' });
             }
 
             let data = {
@@ -322,15 +346,15 @@ export default {
                 oldPos: e.oldIndex,
                 oldParent: e.item._underlying_vm_.relationships.parent.data.id,
                 newParent: e.to.__vue__.$attrs.elementId,
-                sortArray: sortArray
+                sortArray: sortArray,
             };
 
             if (data.oldParent === data.newParent && data.oldPos === data.newPos) {
                 return;
             }
             if (data.oldParent !== data.newParent) {
-                sortArray.splice(data.newPos, 0, {id: data.id, type: 'courseware-structural-elements'});
-            } 
+                sortArray.splice(data.newPos, 0, { id: data.id, type: 'courseware-structural-elements' });
+            }
 
             data.sortArray = sortArray;
             this.$emit('sort', data);
@@ -346,20 +370,25 @@ export default {
                         this.storeKeyboardSorting();
                     } else {
                         this.keyboardSelected = true;
-                        const assistiveLive = 
-                            this.$gettextInterpolate(
-                                this.$gettext('%{elementTitle} ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen. Mit Pfeiltasten links und rechts kann die Position in der Hierarchie verändert werden.'),
-                                { elementTitle: this.element.attributes.title, pos: this.element.attributes.position + 1, listLength: this.siblingCount }
-                            );
+                        const assistiveLive = this.$gettextInterpolate(
+                            this.$gettext(
+                                '%{elementTitle} ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen. Mit Pfeiltasten links und rechts kann die Position in der Hierarchie verändert werden.'
+                            ),
+                            {
+                                elementTitle: this.element.attributes.title,
+                                pos: this.element.attributes.position + 1,
+                                listLength: this.siblingCount,
+                            }
+                        );
 
-                            this.setAssistiveLiveContents(assistiveLive);
+                        this.setAssistiveLiveContents(assistiveLive);
                     }
                     break;
             }
             if (this.keyboardSelected) {
                 const data = {
                     element: this.element,
-                    parents: []
+                    parents: [],
                 };
                 switch (e.keyCode) {
                     case 27: // esc
@@ -371,7 +400,7 @@ export default {
                         this.$emit('moveItemPrevLevel', data);
                         break;
                     case 38: // up
-                        e.preventDefault();    
+                        e.preventDefault();
                         this.$emit('moveItemUp', data);
                         break;
                     case 39: // right
@@ -379,7 +408,7 @@ export default {
                         this.$emit('moveItemNextLevel', data);
                         break;
                     case 40: // down
-                        e.preventDefault(); 
+                        e.preventDefault();
                         this.$emit('moveItemDown', data);
                         break;
                 }
@@ -403,10 +432,9 @@ export default {
         },
         abortKeyboardSorting() {
             this.$emit('childrenUpdated');
-            const assistiveLive = this.$gettextInterpolate(
-                this.$gettext('%{elementTitle}. Neuordnung abgebrochen.'),
-                { elementTitle: this.element.attributes.title }
-            );
+            const assistiveLive = this.$gettextInterpolate(this.$gettext('%{elementTitle}. Neuordnung abgebrochen.'), {
+                elementTitle: this.element.attributes.title,
+            });
             this.setAssistiveLiveContents(assistiveLive);
             this.$nextTick(() => {
                 this.keyboardSelected = false;
@@ -419,14 +447,14 @@ export default {
                 oldPos: this.element.attributes.position,
                 oldParent: this.element.relationships.parent.data.id,
                 newParent: this.element.newParentId,
-                sortArray: this.element.sortArray
+                sortArray: this.element.sortArray,
             };
             this.keyboardSelected = false;
 
             if (data.newParent === undefined || data.newPos === undefined) {
                 const assistiveLive = this.$gettextInterpolate(
                     this.$gettext('%{elementTitle}. Neuordnung nicht möglich.'),
-                    {elementTitle: this.element.attributes.title}
+                    { elementTitle: this.element.attributes.title }
                 );
                 this.setAssistiveLiveContents(assistiveLive);
                 return;
@@ -435,18 +463,18 @@ export default {
             if (data.oldParent === data.newParent && data.oldPos === data.newPos) {
                 const assistiveLive = this.$gettextInterpolate(
                     this.$gettext('%{elementTitle}. Neuordnung abgebrochen.'),
-                    {elementTitle: this.element.attributes.title}
+                    { elementTitle: this.element.attributes.title }
                 );
                 this.setAssistiveLiveContents(assistiveLive);
                 return;
             }
             this.$emit('sort', data);
             const assistiveLive = this.$gettextInterpolate(
-                this.$gettext('%{elementTitle}, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.'), 
-                {elementTitle: this.element.attributes.title, pos: data.newPos + 1, listLength: this.siblingCount }
+                this.$gettext('%{elementTitle}, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.'),
+                { elementTitle: this.element.attributes.title, pos: data.newPos + 1, listLength: this.siblingCount }
             );
             this.setAssistiveLiveContents(assistiveLive);
-        }
+        },
     },
     mounted() {
         if (this.element.relationships?.task?.data) {
@@ -468,6 +496,6 @@ export default {
             this.keyboardSelected = true;
             this.$refs.sortableHandle.focus();
         },
-    }
+    },
 };
 </script>
diff --git a/resources/vue/components/courseware/structural-element/CoursewareTreeItemAdder.vue b/resources/vue/components/courseware/structural-element/CoursewareTreeItemAdder.vue
new file mode 100644
index 0000000000000000000000000000000000000000..fc9ca44bbcbd03f7c6a1d52504d6c9bb1aaa5a65
--- /dev/null
+++ b/resources/vue/components/courseware/structural-element/CoursewareTreeItemAdder.vue
@@ -0,0 +1,120 @@
+<template>
+    <li class="cw-tree-item cw-tree-item-adder">
+        <div class="cw-tree-item-wrapper">
+            <form v-if="showForm" class="cw-tree-item-adder-form" @submit.prevent="">
+                <input type="text" v-model="elementTitle" :placeholder="$gettext('Titel')" />
+                <button class="button accept" :title="$gettext('Seite erstellen')" @click="createElement"></button>
+                <button class="button cancel" :title="$gettext('Abbrechen')" @click="closeForm"></button>
+            </form>
+            <button class="add-element" v-else :title="$gettext('Seite hinzufügen')" @click="showForm = true">
+                <studip-icon shape="add" />
+            </button>
+        </div>
+    </li>
+</template>
+
+<script>
+import { mapActions, mapGetters } from 'vuex';
+
+export default {
+    name: 'courseware-tree-item-adder',
+    props: {
+        parentId: {
+            type: String,
+            required: true,
+        },
+    },
+    data() {
+        return {
+            showForm: false,
+            elementTitle: '',
+        };
+    },
+    computed: {
+        ...mapGetters({
+            lastCreatedStructuralElement: 'courseware-structural-elements/lastCreated',
+            structuralElementById: 'courseware-structural-elements/byId',
+            currentElement: 'currentElement',
+        }),
+    },
+    methods: {
+        ...mapActions({
+            createStructuralElementWithTemplate: 'createStructuralElementWithTemplate',
+            loadStructuralElementById: 'courseware-structural-elements/loadById',
+            companionError: 'companionError',
+            companionInfo: 'companionInfo',
+        }),
+        closeForm() {
+            this.showForm = false;
+            this.elementTitle = '';
+        },
+        async createElement() {
+            this.elementTitle = this.elementTitle.trim();
+            if (this.elementTitle === '') {
+                this.companionInfo({ info: this.$gettext('Bitte geben Sie einen Titel für die neue Seite ein.') });
+
+                return;
+            }
+
+            const element = {
+                attributes: {
+                    title: this.elementTitle,
+                    purpose: 'content',
+                    payload: {
+                        description: '',
+                        color: 'studip-blue',
+                        license_type: '',
+                        required_time: '',
+                        difficulty_start: '',
+                        difficulty_end: '',
+                    },
+                },
+                templateId: null,
+                parentId: this.parentId,
+                currentId: this.currentElement,
+            };
+
+            this.closeForm();
+
+            try {
+                await this.createStructuralElementWithTemplate(element);
+            } catch (e) {
+                let errorMessage = this.$gettext(
+                    'Es ist ein Fehler aufgetreten. Die Seite konnte nicht erstellt werden.'
+                );
+                if (e.status === 403) {
+                    errorMessage = this.$gettext(
+                        'Die Seite konnte nicht erstellt werden. Sie haben nicht die notwendigen Schreibrechte.'
+                    );
+                }
+
+                this.companionError({ info: errorMessage });
+                return;
+            }
+
+            const newCreated = this.lastCreatedStructuralElement;
+            await this.loadStructuralElementById({ id: newCreated.id });
+            const newElement = this.structuralElementById({ id: newCreated.id });
+
+            this.$router.push(newElement.id);
+        },
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.cw-tree-root-list > .cw-tree-item.cw-tree-item-adder > .cw-tree-item-wrapper {
+    border-bottom: none;
+}
+.cw-tree-item-adder {
+    .add-element {
+        border: none;
+        cursor: pointer;
+        background-color: transparent;
+        height: 28px;
+        img {
+            vertical-align: middle;
+        }
+    }
+}
+</style>
diff --git a/resources/vue/components/courseware/structural-element/CoursewareTreeItemUpdater.vue b/resources/vue/components/courseware/structural-element/CoursewareTreeItemUpdater.vue
new file mode 100644
index 0000000000000000000000000000000000000000..78690c9684156f719020a47e16d4fb3b317bab0a
--- /dev/null
+++ b/resources/vue/components/courseware/structural-element/CoursewareTreeItemUpdater.vue
@@ -0,0 +1,91 @@
+<template>
+    <form class="cw-tree-item-updater" @submit.prevent="">
+        <input type="text" v-model="elementTitle" :placeholder="$gettext('Titel')" />
+        <button class="button accept" :title="$gettext('Speichern')" @click="updateElement"></button>
+        <button class="button cancel" :title="$gettext('Abbrechen')" @click="close"></button>
+    </form>
+</template>
+
+<script>
+import { mapActions, mapGetters } from 'vuex';
+
+export default {
+    name: 'courseware-tree-item-adder',
+    props: {
+        structuralElement: {
+            type: Object,
+            required: true,
+        },
+    },
+    data() {
+        return {
+            elementTitle: '',
+        };
+    },
+    computed: {
+        ...mapGetters({
+            structuralElementById: 'courseware-structural-elements/byId',
+            userId: 'userId',
+            userById: 'users/byId',
+        }),
+    },
+    methods: {
+        ...mapActions({
+            loadStructuralElementById: 'courseware-structural-elements/loadById',
+            companionError: 'companionError',
+            companionInfo: 'companionInfo',
+
+            updateStructuralElement: 'updateStructuralElement',
+            lockObject: 'lockObject',
+            unlockObject: 'unlockObject',
+            loadUser: 'users/loadById',
+        }),
+        close() {
+            this.$emit('close');
+        },
+        async updateElement() {
+            if (this.elementTitle === '') {
+                this.companionInfo({
+                    info: this.$gettext('Bitte geben Sie einen Titel für die Seite ein.'),
+                });
+                return;
+            }
+            await this.loadStructuralElementById({ id: this.structuralElement.id });
+            let element = this.structuralElementById({ id: this.structuralElement.id });
+            element.attributes.title = this.elementTitle;
+            const blockerData = element?.relationships?.['edit-blocker']?.data;
+            const blocked = blockerData !== null && blockerData !== '';
+            const blockedByAnotherUser = blocked && blockerData.id !== this.userId;
+            if (blockedByAnotherUser) {
+                this.close();
+                await this.loadUser({ id: blockerData.id });
+                const blocker = this.userById({ id: blockerData.id });
+                this.companionWarning({
+                    info: this.$gettextInterpolate(
+                        this.$gettext(
+                            'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.'
+                        ),
+                        { blockingUserName: blocker.attributes['formatted-name'] }
+                    ),
+                });
+                return;
+            }
+            if (!this.blocked) {
+                await this.lockObject({ id: this.structuralElement.id, type: 'courseware-structural-elements' });
+            }
+
+            await this.lockObject({ id: this.structuralElement.id, type: 'courseware-structural-elements' });
+            await this.updateStructuralElement({ element, id: this.structuralElement.id });
+            await this.unlockObject({ id: this.structuralElement.id, type: 'courseware-structural-elements' });
+            this.$emit('childrenUpdated');
+            this.close();
+        },
+        setTitle() {
+            this.elementTitle = this.structuralElement.attributes.title;
+        },
+    },
+    mounted() {
+        this.setTitle();
+    },
+};
+</script>