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

Courseware: Übersicht der Lernmaterialien in Inhaltsverzeichnis anzeigen

Closes #4477

Merge request studip/studip!3263
parent 330ae492
No related branches found
No related tags found
No related merge requests found
...@@ -84,7 +84,12 @@ $companion-types: ( ...@@ -84,7 +84,12 @@ $companion-types: (
margin-top: 8px; margin-top: 8px;
} }
p { &.borderless {
border: none;
}
.cw-companion-message {
margin: 0 1em 10px 0; margin: 0 1em 10px 0;
color: var(--black);
} }
} }
\ No newline at end of file
<template> <template>
<div class="cw-companion-box" :class="[mood]"> <div class="cw-companion-box" :class="[mood, border ? '' : 'borderless' ]">
<div> <div>
<p v-html="msgCompanion"></p> <p class="cw-companion-message" v-html="msgCompanion"></p>
<slot name="companionActions"></slot> <slot name="companionActions"></slot>
</div> </div>
</div> </div>
...@@ -18,6 +18,10 @@ export default { ...@@ -18,6 +18,10 @@ export default {
validator: value => { validator: value => {
return ['default','unsure', 'special', 'sad', 'pointing', 'curious'].includes(value); return ['default','unsure', 'special', 'sad', 'pointing', 'curious'].includes(value);
} }
},
border: {
type: Boolean,
default: true
} }
} }
}; };
......
...@@ -21,6 +21,15 @@ ...@@ -21,6 +21,15 @@
id="cw-ribbon-tool-contents" id="cw-ribbon-tool-contents"
/> />
</courseware-tab> </courseware-tab>
<courseware-tab
:name="$gettext('Lernmaterialien')"
:selected="showUnits"
alias="units"
ref="units"
:index="1"
>
<CoursewareToolsUnits />
</courseware-tab>
</courseware-tabs> </courseware-tabs>
<button <button
:title="$gettext('schließen')" :title="$gettext('schließen')"
...@@ -37,6 +46,7 @@ ...@@ -37,6 +46,7 @@
import CoursewareTabs from '../layouts/CoursewareTabs.vue'; import CoursewareTabs from '../layouts/CoursewareTabs.vue';
import CoursewareTab from '../layouts/CoursewareTab.vue'; import CoursewareTab from '../layouts/CoursewareTab.vue';
import CoursewareToolsContents from './CoursewareToolsContents.vue'; import CoursewareToolsContents from './CoursewareToolsContents.vue';
import CoursewareToolsUnits from './CoursewareToolsUnits.vue';
import { FocusTrap } from 'focus-trap-vue'; import { FocusTrap } from 'focus-trap-vue';
import { mapActions, mapGetters } from 'vuex'; import { mapActions, mapGetters } from 'vuex';
...@@ -46,6 +56,7 @@ export default { ...@@ -46,6 +56,7 @@ export default {
CoursewareTabs, CoursewareTabs,
CoursewareTab, CoursewareTab,
CoursewareToolsContents, CoursewareToolsContents,
CoursewareToolsUnits,
FocusTrap, FocusTrap,
}, },
props: { props: {
...@@ -67,7 +78,7 @@ export default { ...@@ -67,7 +78,7 @@ export default {
data() { data() {
return { return {
showContents: true, showContents: true,
showBlockAdder: false, showUnits: false,
trap: false, trap: false,
initialFocusElement: null initialFocusElement: null
}; };
...@@ -94,7 +105,7 @@ export default { ...@@ -94,7 +105,7 @@ export default {
}, },
methods: { methods: {
...mapActions({ ...mapActions({
coursewareContainerAdder: 'coursewareContainerAdder' coursewareContainerAdder: 'coursewareContainerAdder',
}), }),
scrollToCurrent() { scrollToCurrent() {
setTimeout(() => { setTimeout(() => {
......
<template>
<StudipProgressIndicator v-if="loadingUnits" :description="$gettext('Vorgang wird bearbeitet...')" />
<ul v-else class="cw-ribbon-tools-units">
<li v-for="unit in units" :key="unit.id">
<CoursewareToolsUnitsItem :unit="unit" :element="getUnitElement(unit)" />
</li>
<li v-if="emptyUnits">
<CoursewareCompanionBox mood="sad" :msgCompanion="emptyUnitsMessage" :border="false"/>
</li>
</ul>
</template>
<script>
import CoursewareToolsUnitsItem from './CoursewareToolsUnitsItem.vue';
import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue';
import StudipProgressIndicator from '../../StudipProgressIndicator.vue';
import { mapActions, mapGetters } from 'vuex';
export default {
name: 'CoursewareToolsUnits',
components: {
CoursewareToolsUnitsItem,
CoursewareCompanionBox,
StudipProgressIndicator,
},
data() {
return {
loadingUnits: false,
};
},
computed: {
...mapGetters({
context: 'context',
coursewareUnits: 'courseware-units/all',
currentUnit: 'currentUnit',
elementById: 'courseware-structural-elements/byId',
userId: 'userId',
}),
units() {
return (
this.coursewareUnits
.filter(
(unit) =>
unit.relationships.range.data.id === this.context.id && unit.id !== this.currentUnit.id
)
.sort((a, b) => a.attributes.position - b.attributes.position) ?? []
);
},
inCourseContext() {
return this.context.type === 'courses';
},
inUserContext() {
return this.context.type === 'users';
},
emptyUnits() {
return this.units.length === 0;
},
emptyUnitsMessage() {
if (this.inCourseContext) {
return this.$gettext('Es wurden keine weiteren Lernmaterialien in dieser Veranstaltung gefunden.');
}
if (this.inUserContext) {
return this.$gettext('Es wurden keine weiteren Lernmaterialien gefunden.');
}
return '';
}
},
methods: {
...mapActions({
loadCourseUnits: 'loadCourseUnits',
loadUserUnits: 'loadUserUnits',
}),
getUnitElement(unit) {
const elementId = unit.relationships['structural-element'].data.id;
return this.elementById({ id: elementId });
},
},
async beforeMount() {
if (this.coursewareUnits.length === 0) {
this.loadingUnits = true;
}
if (this.inCourseContext) {
await this.loadCourseUnits(this.context.id);
}
if (this.inUserContext) {
await this.loadUserUnits(this.userId);
}
this.loadingUnits = false;
},
};
</script>
<style lang="scss">
.cw-ribbon-tools-units {
list-style: none;
padding: 0;
li {
margin-bottom: 2em;
}
}
</style>
<template>
<a v-if="element" class="cw-tools-units-item-header" :href="url">
<studip-ident-image v-model="identimage" :baseColor="headerColor.hex" :pattern="element.attributes.title" />
<div class="cw-tools-units-item-header-image" :style="headerImageStyle"></div>
<div class="cw-tools-units-item-header-details">
<header>{{ element.attributes.title }}</header>
<p>{{ element.attributes.payload.description }}</p>
</div>
</a>
</template>
<script>
import StudipIdentImage from '../../StudipIdentImage.vue';
import colorMixin from '@/vue/mixins/courseware/colors.js';
import { mapActions, mapGetters } from 'vuex';
export default {
name: 'CoursewareToolsUnitsItem',
mixins: [colorMixin],
components: {
StudipIdentImage,
},
props: {
unit: Object,
element: Object,
},
data() {
return {
identimage: '',
};
},
computed: {
...mapGetters({
context: 'context',
}),
headerImageUrl() {
return this.element.relationships?.image?.meta?.['download-url'];
},
headerImageStyle() {
if (this.headerImageUrl) {
return { 'background-image': 'url(' + this.headerImageUrl + ')' };
}
return { 'background-image': 'url(' + this.identimage + ')' };
},
headerColor() {
const rootColor = this.element?.attributes?.payload?.color ?? 'studip-blue';
return this.mixinColors.find((color) => color.class === rootColor);
},
inCourseContext() {
return this.context.type === 'courses';
},
url() {
if (this.inCourseContext) {
return STUDIP.URLHelper.getURL('dispatch.php/course/courseware/courseware/' + this.unit.id, {
cid: this.context.id,
});
} else {
return STUDIP.URLHelper.getURL('dispatch.php/contents/courseware/courseware/' + this.unit.id);
}
},
}
};
</script>
<style lang="scss">
.cw-tools-units-item-header {
display: flex;
flex-direction: row;
height: 100px;
margin-top: 8px;
.cw-tools-units-item-header-image {
height: 100px;
width: 150px;
min-width: 150px;
background-size: 100% auto;
background-repeat: no-repeat;
background-position: center;
background-color: var(--content-color-20);
}
.cw-tools-units-item-header-details {
margin: 0 8px;
display: -webkit-box;
overflow: hidden;
height: 100px;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
header {
margin: 0 0 6px 0;
font-size: 16px;
line-height: 16px;
}
p {
margin: 0;
color: var(--black);
}
}
}
</style>
\ No newline at end of file
...@@ -103,6 +103,13 @@ const getters = { ...@@ -103,6 +103,13 @@ const getters = {
const id = getters.currentElement; const id = getters.currentElement;
return rootGetters['courseware-structural-elements/byId']({ id }); return rootGetters['courseware-structural-elements/byId']({ id });
}, },
currentUnit(state, getters, rootState, rootGetters) {
const id = getters.currentStructuralElement.relationships?.unit?.data?.id;
if (id) {
return rootGetters['courseware-units/byId']({ id });
}
return null;
},
currentElementBlocked(state, getters, rootState, rootGetters) { currentElementBlocked(state, getters, rootState, rootGetters) {
const elemData = getters.currentStructuralElement?.relationships?.['edit-blocker']?.data; const elemData = getters.currentStructuralElement?.relationships?.['edit-blocker']?.data;
return elemData !== null && elemData !== '' && getters.currentStructuralElement; return elemData !== null && elemData !== '' && getters.currentStructuralElement;
......
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