Skip to content
Snippets Groups Projects
Commit c4ec909e authored by mlunzena's avatar mlunzena Committed by Ron Lucke
Browse files

fix courseware's contentbar navigation

Fixes #280.
parent ac2575c6
No related branches found
No related tags found
No related merge requests found
......@@ -396,7 +396,7 @@
<script>
import ContainerComponents from './container-components.js';
import CoursewarePluginComponents from './plugin-components.js'
import CoursewarePluginComponents from './plugin-components.js';
import CoursewareStructuralElementPermissions from './CoursewareStructuralElementPermissions.vue';
import CoursewareAccordionContainer from './CoursewareAccordionContainer.vue';
import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
......@@ -430,7 +430,7 @@ export default {
IsoDate,
StudipDialog,
},
props: {},
props: ['orderedStructuralElements'],
mixins: [CoursewareExport],
......@@ -481,6 +481,9 @@ export default {
courseware: 'courseware',
consumeMode: 'consumeMode',
containerById: 'courseware-containers/byId',
relatedContainers: 'courseware-containers/related',
relatedStructuralElements: 'courseware-structural-elements/related',
relatedUsers: 'users/related',
structuralElementById: 'courseware-structural-elements/byId',
userIsTeacher: 'userIsTeacher',
pluginManager: 'pluginManager',
......@@ -488,13 +491,13 @@ export default {
showAddDialog: 'showStructuralElementAddDialog',
showExportDialog: 'showStructuralElementExportDialog',
showInfoDialog: 'showStructuralElementInfoDialog',
showDeleteDialog : 'showStructuralElementDeleteDialog',
showOerDialog : 'showStructuralElementOerDialog',
showDeleteDialog: 'showStructuralElementDeleteDialog',
showOerDialog: 'showStructuralElementOerDialog',
oerEnabled: 'oerEnabled',
oerTitle: 'oerTitle',
licenses: 'licenses',
exportState: 'exportState',
exportProgress: 'exportProgress'
exportProgress: 'exportProgress',
}),
textOer() {
......@@ -502,7 +505,7 @@ export default {
title: this.$gettext('Seite auf') + ' ' + this.oerTitle + ' ' + this.$gettext('veröffentlichen'),
confirm: this.$gettext('Veröffentlichen'),
close: this.$gettext('Schließen'),
}
};
},
inCourse() {
......@@ -555,87 +558,38 @@ export default {
},
ancestors() {
if (!this.currentElement) {
return [];
}
if (this.currentElement.relationships.ancestors.data) {
return this.currentElement.relationships.ancestors.data.map(({ id }) =>
this.structuralElementById({ id })
);
}
return [];
},
parent() {
if (!this.structuralElement) {
return [];
}
if (this.structuralElement.relationships.parent.data) {
let id = this.structuralElement.relationships.parent.data.id;
return this.structuralElementById({ id });
}
return [];
},
hasSiblings() {
if (this.parent.length !== 0) {
return this.parent.relationships.children.data.length > 1;
} else {
return false;
}
return this.relatedStructuralElements({ parent: this.structuralElement, relationship: 'ancestors' });
},
prevElement() {
if (this.hasSiblings) {
let view = this;
let siblings = this.parent.relationships.children.data;
let id = '';
siblings.forEach((el, index) => {
if (el.id === view.currentId && index !== 0) {
id = siblings[index - 1].id;
}
});
if (id === '') {
return this.parent;
} else {
return this.structuralElementById({ id });
}
} else if (this.parent.length !== 0) {
return this.parent;
} else {
const currentIndex = this.orderedStructuralElements.indexOf(this.structuralElement.id);
if (currentIndex <= 0) {
return null;
}
const previousId = this.orderedStructuralElements[currentIndex - 1];
const previous = this.structuralElementById({ id: previousId });
return previous;
},
nextElement() {
let view = this;
if (this.structuralElement.relationships.children.data.length > 0) {
let id = this.structuralElement.relationships.children.data[0].id;
return this.structuralElementById({ id });
} else if (this.hasSiblings) {
let siblings = this.parent.relationships.children.data;
let id = '';
siblings.forEach((el, index) => {
if (el.id === view.currentId && siblings.length > index + 1) {
id = siblings[index + 1].id;
}
});
if (id === '') {
return this.getNextParentSibling(this.currentId);
} else {
return this.structuralElementById({ id });
}
} else {
return this.getNextParentSibling(this.currentId);
const currentIndex = this.orderedStructuralElements.indexOf(this.structuralElement.id);
const lastIndex = this.orderedStructuralElements.length - 1;
if (currentIndex === -1 || currentIndex === lastIndex) {
return null;
}
const nextId = this.orderedStructuralElements[currentIndex + 1];
const next = this.structuralElementById({ id: nextId });
return next;
},
empty() {
if (this.containers === null) {
return true;
} else {
let noBlockFound = true;
this.containers.forEach((container) => {
if (container.relationships.blocks.data.length > 0) {
noBlockFound = false;
}
});
return noBlockFound;
return !this.containers.some((container) => container.relationships.blocks.data.length > 0);
}
},
containers() {
......@@ -643,12 +597,12 @@ export default {
return [];
}
const containers = this.$store.getters['courseware-containers/related']({
parent: this.structuralElement,
relationship: 'containers',
});
return containers;
return (
this.relatedContainers({
parent: this.structuralElement,
relationship: 'containers',
}) ?? []
);
},
noContainers() {
if (this.containers === null) {
......@@ -679,7 +633,7 @@ export default {
},
owner() {
const owner = this.$store.getters['users/related']({
const owner = this.relatedUsers({
parent: this.structuralElement,
relationship: 'owner',
});
......@@ -688,7 +642,7 @@ export default {
},
editor() {
const editor = this.$store.getters['users/related']({
const editor = this.relatedUsers({
parent: this.structuralElement,
relationship: 'editor',
});
......@@ -764,7 +718,7 @@ export default {
},
},
async mounted() {
mounted() {
if (!this.currentId) {
this.setCurrentId(this.$route.params.id);
}
......@@ -797,7 +751,7 @@ export default {
this.initCurrent();
},
initCurrent() {
this.currentElement = JSON.parse(JSON.stringify(this.structuralElement));
this.currentElement = _.cloneDeep(this.structuralElement);
this.uploadFileError = '';
},
async menuAction(action) {
......@@ -941,29 +895,6 @@ export default {
containerComponent(container) {
return 'courseware-' + container.attributes['container-type'] + '-container';
},
getNextParentSibling(element_id) {
let current = this.structuralElementById({ id: element_id });
if (current.relationships.parent.data === null) {
return null;
}
let parent = this.structuralElementById({ id: current.relationships.parent.data.id });
if (parent.relationships.parent.data === null) {
return null;
}
let grandParent = this.structuralElementById({ id: parent.relationships.parent.data.id });
let parentSiblings = grandParent.relationships.children.data;
let id = '';
parentSiblings.forEach((el, index) => {
if (parseInt(el.id, 10) === parseInt(parent.id, 10) && parentSiblings.length > index + 1) {
id = parentSiblings[index + 1].id;
}
});
if (id === '') {
this.getNextParentSibling(parent.id);
} else {
return this.structuralElementById({ id });
}
},
setBookmark() {
this.addBookmark(this.structuralElement);
this.companionInfo({ info: this.$gettext('Das Lesezeichen wurde gesetzt') });
......
<template>
<div v-if="courseware">
<courseware-structural-element></courseware-structural-element>
<courseware-structural-element
:ordered-structural-elements="orderedStructuralElements"
></courseware-structural-element>
<MountingPortal mountTo="#courseware-action-widget" name="sidebar-actions">
<courseware-action-widget></courseware-action-widget>
</MountingPortal>
......@@ -25,8 +27,14 @@ export default {
CoursewareViewWidget,
CoursewareActionWidget,
},
data: () => ({ orderedStructuralElements: [] }),
computed: {
...mapGetters(['courseware', 'userId', 'blockAdder']),
...mapGetters({
courseware: 'courseware',
relatedStructuralElement: 'courseware-structural-elements/related',
structuralElements: 'courseware-structural-elements/all',
userId: 'userId',
}),
},
methods: {
...mapActions(['loadCoursewareStructure', 'loadTeacherStatus', 'coursewareBlockAdder']),
......@@ -34,12 +42,54 @@ export default {
async mounted() {
await this.loadCoursewareStructure();
await this.loadTeacherStatus(this.userId);
// console.debug('IndexApp mounted for courseware:', this.courseware, this.$store);
},
watch: {
$route() {
this.coursewareBlockAdder({}); //reset block adder on navigate
},
structuralElements(newElements, oldElements) {
const nodes = buildNodes(this.structuralElements, this.relatedStructuralElement.bind(this));
this.orderedStructuralElements = [...visitTree(nodes, findRoot(nodes))];
},
},
};
function buildNodes(structuralElements, relatedStructuralElement) {
return structuralElements.reduce((memo, element) => {
memo.push({
id: element.id,
parent:
relatedStructuralElement({
parent: element,
relationship: 'parent',
})?.id ?? null,
children:
relatedStructuralElement({
parent: element,
relationship: 'children',
})?.map((child) => child.id) ?? [],
});
return memo;
}, []);
}
function findRoot(nodes) {
return nodes.find((node) => node.parent === null);
}
function findNode(nodes, id) {
return nodes.find((node) => node.id === id);
}
function* visitTree(nodes, current) {
if (current) {
yield current.id;
for (let index = 0; index < current.children.length; index++) {
yield* visitTree(nodes, findNode(nodes, current.children[index]));
}
}
};
}
</script>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment