Merged in feature/content-actions (pull request #29)
Feature/content actions Approved-by: Christian Cueni <christian.cueni@iterativ.ch>
This commit is contained in:
commit
18b6079d26
|
|
@ -46,7 +46,7 @@
|
|||
}
|
||||
|
||||
&__icon {
|
||||
height: 57px;
|
||||
width: 40px;
|
||||
fill: $color-silver-dark;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
{{chapter.description}}
|
||||
</p>
|
||||
|
||||
<add-content-block-button :parent="chapter.id"></add-content-block-button>
|
||||
<add-content-block-button :parent="chapter.id" v-if="editModule"></add-content-block-button>
|
||||
|
||||
<content-block :contentBlock="contentBlock"
|
||||
:parent="chapter.id"
|
||||
|
|
@ -19,6 +19,8 @@
|
|||
import ContentBlock from '@/components/ContentBlock';
|
||||
import AddContentBlockButton from '@/components/AddContentBlockButton';
|
||||
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
props: ['chapter', 'index'],
|
||||
|
||||
|
|
@ -36,6 +38,7 @@
|
|||
currentFilter() {
|
||||
return this.$store.state.filterForSchoolClass;
|
||||
},
|
||||
...mapGetters(['editModule'])
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
<template>
|
||||
<div class="content-block__container">
|
||||
<div class="content-block" :class="specialClass">
|
||||
<!--div class="content-block__actions">
|
||||
<div class="content-block__actions">
|
||||
<visibility-action
|
||||
v-if="!contentBlock.indent"
|
||||
:block="contentBlock"></visibility-action>
|
||||
<a @click="editContentBlock()" v-if="canEditContentBlock" class="content-block__action-button">
|
||||
<pen-icon class="content-block__action-icon action-icon"></pen-icon>
|
||||
</a>
|
||||
<a @click="deleteContentBlock(contentBlock.id)" v-if="canEditContentBlock" class="content-block__action-button">
|
||||
<trash-icon class="content-block__action-icon action-icon"></trash-icon>
|
||||
</a>
|
||||
</div-->
|
||||
<!--<a @click="editContentBlock()" v-if="canEditContentBlock" class="content-block__action-button">-->
|
||||
<!--<pen-icon class="content-block__action-icon action-icon"></pen-icon>-->
|
||||
<!--</a>-->
|
||||
<!--<a @click="deleteContentBlock(contentBlock.id)" v-if="canEditContentBlock" class="content-block__action-button">-->
|
||||
<!--<trash-icon class="content-block__action-icon action-icon"></trash-icon>-->
|
||||
<!--</a>-->
|
||||
</div>
|
||||
|
||||
<h3 v-if="instrumentLabel !== ''" class="content-block__instrument-label">{{instrumentLabel}}</h3>
|
||||
<h4 class="content-block__title" v-if="!contentBlock.indent">{{contentBlock.title}}</h4>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
</div>
|
||||
|
||||
<add-content-block-button :after="contentBlock.id" v-if="!contentBlock.indent"></add-content-block-button>
|
||||
<add-content-block-button :after="contentBlock.id" v-if="!contentBlock.indent && editModule"></add-content-block-button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -55,6 +55,8 @@
|
|||
import CHAPTER_QUERY from '@/graphql/gql/chapterQuery.gql';
|
||||
import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';
|
||||
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
const instruments = {
|
||||
base_communication: 'Sprache & Kommunikation',
|
||||
base_society: 'Gesellschaft'
|
||||
|
|
@ -89,6 +91,7 @@
|
|||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['editModule']),
|
||||
specialClass() {
|
||||
return `content-block--${this.contentBlock.type.toLowerCase()}`
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<template>
|
||||
<svg id="shape" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<path
|
||||
d="M70.26 20.26A29.77 29.77 0 0 0 40.59 48H2a2 2 0 1 0 0 4h38.6a29.74 29.74 0 1 0 29.66-31.74zm0 55.5A25.76 25.76 0 1 1 96 50a25.78 25.78 0 0 1-25.74 25.76z"/>
|
||||
<path d="M82.24 48h-10V38a2 2 0 0 0-4 0v10h-10a2 2 0 1 0 0 4h10v10a2 2 0 0 0 4 0V52h10a2 2 0 1 0 0-4z"/>
|
||||
d="M61.74,13.24a36.43,36.43,0,0,0-22.06,7.35L2.52,48a2.5,2.5,0,0,0,0,4L39.66,79.39A36.76,36.76,0,1,0,61.74,13.24Zm0,68.52a31.5,31.5,0,0,1-19.09-6.38L8.21,50,42.66,24.6A31.76,31.76,0,1,1,61.74,81.76Z"/>
|
||||
<path
|
||||
d="M79.64,47.5H64.51V32.38a2.5,2.5,0,0,0-5,0V47.5H44.39a2.5,2.5,0,0,0,0,5H59.51V67.63a2.5,2.5,0,0,0,5,0V52.5H79.64a2.5,2.5,0,0,0,0-5Z"/>
|
||||
</svg>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<template>
|
||||
<svg id="shape" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<path
|
||||
d="M99.5,48.11a56.91,56.91,0,0,0-21-21.19L91.18,14.26a3.85,3.85,0,1,0-5.44-5.44L71.21,23.36A56.73,56.73,0,0,0,.5,48.11a3.84,3.84,0,0,0,0,3.79,56.92,56.92,0,0,0,21,21.19L8.82,85.74a3.85,3.85,0,1,0,5.44,5.44L28.79,76.64A56.66,56.66,0,0,0,50,80.79,57,57,0,0,0,99.5,51.89,3.84,3.84,0,0,0,99.5,48.11ZM8.32,50a49.09,49.09,0,0,1,56.9-20.66L27.15,67.42A49.25,49.25,0,0,1,8.32,50ZM50,73.09a49,49,0,0,1-15.22-2.43L72.85,32.59A49.25,49.25,0,0,1,91.68,50,49.27,49.27,0,0,1,50,73.09Z"/>
|
||||
</svg>
|
||||
</template>
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
<template>
|
||||
<svg id="shape" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<path
|
||||
d="M98.31,45.1a61.77,61.77,0,0,0-21-17.19A60.61,60.61,0,0,0,50.78,21.5H49.23a60.59,60.59,0,0,0-26.55,6.41,61.77,61.77,0,0,0-21,17.19,8,8,0,0,0,0,9.81,61.75,61.75,0,0,0,21,17.19A60.55,60.55,0,0,0,49.22,78.5h1.55a60.58,60.58,0,0,0,26.55-6.41,61.82,61.82,0,0,0,21-17.19A8,8,0,0,0,98.31,45.1ZM78.51,50a28.54,28.54,0,0,0-8.16-19.94c1.64.64,3.25,1.35,4.83,2.14A57,57,0,0,1,94.53,48a3.19,3.19,0,0,1,0,3.92A57,57,0,0,1,75.18,67.81c-1.56.78-3.18,1.49-4.82,2.13A28.56,28.56,0,0,0,78.51,50Zm-4.79,0A23.72,23.72,0,1,1,50,26.28,23.74,23.74,0,0,1,73.72,50ZM29.65,69.94c-1.64-.64-3.26-1.35-4.83-2.14A57,57,0,0,1,5.47,52a3.18,3.18,0,0,1,0-3.92A57,57,0,0,1,24.82,32.19c1.57-.78,3.19-1.5,4.83-2.14a28.46,28.46,0,0,0,0,39.88Z"/>
|
||||
<path
|
||||
d="M50,39.31A10.69,10.69,0,1,0,60.69,50,10.7,10.7,0,0,0,50,39.31ZM55.9,50A5.9,5.9,0,1,1,50,44.1,5.9,5.9,0,0,1,55.9,50Z"/>
|
||||
d="M99.5,48.11a56.85,56.85,0,0,0-99,0,3.84,3.84,0,0,0,0,3.79,56.85,56.85,0,0,0,99,0A3.84,3.84,0,0,0,99.5,48.11ZM50,30.75A12.31,12.31,0,1,1,37.69,43.06,12.32,12.32,0,0,1,50,30.75Zm0,42.34A49.28,49.28,0,0,1,8.32,50,49.3,49.3,0,0,1,35.75,29a20,20,0,1,0,28.5,0A49.3,49.3,0,0,1,91.68,50,49.28,49.28,0,0,1,50,73.09Z"/>
|
||||
</svg>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,10 @@
|
|||
module: {
|
||||
required: true,
|
||||
type: Object
|
||||
},
|
||||
edit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="module-navigation__toggle-menu" v-if="canManageContent">
|
||||
<toggle-editing></toggle-editing>
|
||||
</div>
|
||||
|
||||
<!--toggle-solutions-for-module
|
||||
v-if="onModulePage && module.id"
|
||||
:module="module.id"
|
||||
|
|
@ -47,7 +51,8 @@
|
|||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||
|
||||
import SubNavigationItem from '@/components/book-navigation/SubNavigationItem';
|
||||
import ToggleSolutionsForModule from '@/components/ToggleSolutionsForModule';
|
||||
import ToggleSolutionsForModule from '@/components/toggle-menu/ToggleSolutionsForModule';
|
||||
import ToggleEditing from '@/components/toggle-menu/ToggleEditing';
|
||||
|
||||
export default {
|
||||
apollo: {
|
||||
|
|
@ -59,7 +64,8 @@
|
|||
|
||||
components: {
|
||||
SubNavigationItem,
|
||||
ToggleSolutionsForModule
|
||||
ToggleSolutionsForModule,
|
||||
ToggleEditing
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
|
@ -76,6 +82,9 @@
|
|||
return [...this.module.assignments].sort((a, b) => {
|
||||
return a.title.toLowerCase() > b.title.toLowerCase() ? 1 : -1;
|
||||
})
|
||||
},
|
||||
canManageContent() {
|
||||
return this.me.permissions.includes('users.can_manage_school_class_content');
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -152,7 +161,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
&__solution-toggle {
|
||||
&__toggle-menu {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div class="toggle-editing">
|
||||
<checkbox label="Modul anpassen" :checked="checked" @input="toggle"></checkbox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Checkbox from '@/components/Checkbox';
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Checkbox,
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters({
|
||||
checked: 'editModule',
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions({
|
||||
toggle: 'editModule'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -1,40 +1,87 @@
|
|||
<template>
|
||||
<div class="visibility-action">
|
||||
<a @click="toggleVisibility()" v-if="canManageContent" class="visibility-action__action-button">
|
||||
<eye-icon class="visibility-action__action-icon action-icon"></eye-icon>
|
||||
<closed-eye-icon v-if="hidden" class="visibility-action__action-icon action-icon"></closed-eye-icon>
|
||||
<eye-icon v-else class="visibility-action__action-icon action-icon"></eye-icon>
|
||||
</a>
|
||||
<visibility-popover
|
||||
@hide-me="showVisibility = false"
|
||||
:show="showVisibility"
|
||||
:block="block"
|
||||
class="visibility-action__visibility-menu"
|
||||
></visibility-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EyeIcon from '@/components/icons/EyeIcon';
|
||||
import VisibilityPopover from '@/components/visibility/VisibilityPopover';
|
||||
import ClosedEyeIcon from '@/components/icons/ClosedEyeIcon';
|
||||
|
||||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||
import CHANGE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/mutateContentBlock.gql';
|
||||
// import UPDATE_OBJECTIVE_GROUP_VISIBILITY_MUTATION from '@/graphql/gql/mutations/updateObjectiveGroupVisibility.gql';
|
||||
|
||||
export default {
|
||||
props: ['block'],
|
||||
|
||||
components: {
|
||||
VisibilityPopover,
|
||||
EyeIcon
|
||||
EyeIcon,
|
||||
ClosedEyeIcon
|
||||
},
|
||||
|
||||
computed: {
|
||||
canManageContent() {
|
||||
return this.me.permissions.includes('users.can_manage_school_class_content');
|
||||
},
|
||||
isContentBlock() {
|
||||
return this.block.__typename === 'ContentBlockNode';
|
||||
},
|
||||
schoolClass() {
|
||||
return this.me.selectedClass || {id: 'U2Nob29sQ2xhc3NOb2RlOjE='}; // todo: remove after merge with select class feature
|
||||
},
|
||||
hidden() {
|
||||
// is this content block / objective group user created?
|
||||
return (this.isContentBlock ? this.block.userCreated : !!this.block.owner)
|
||||
// if so, is visibility not explicitly set for this school class?
|
||||
? this.block.visibleFor.findIndex(el => el.id === this.schoolClass.id) === -1
|
||||
// otherwise, is it explicitly hidden for this school class?
|
||||
: this.block.hiddenFor.findIndex(el => el.id === this.schoolClass.id) > -1;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleVisibility() {
|
||||
this.showVisibility = !this.showVisibility;
|
||||
let hidden = !this.hidden;
|
||||
let schoolClassId = this.schoolClass.id;
|
||||
|
||||
const visibility = [{
|
||||
schoolClassId,
|
||||
hidden
|
||||
}];
|
||||
|
||||
let mutation, variables;
|
||||
const id = this.block.id;
|
||||
|
||||
if (this.isContentBlock) {
|
||||
mutation = CHANGE_CONTENT_BLOCK_MUTATION;
|
||||
variables = {
|
||||
input: {
|
||||
id,
|
||||
contentBlock: {
|
||||
visibility
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// todo: refactor for single objectives when concept is clear
|
||||
// else {
|
||||
// mutation = UPDATE_OBJECTIVE_GROUP_VISIBILITY_MUTATION;
|
||||
// variables = {
|
||||
// input: {
|
||||
// id,
|
||||
// visibility
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
this.$apollo.mutate({
|
||||
mutation,
|
||||
variables
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
|
|
@ -57,6 +104,7 @@
|
|||
|
||||
<style scoped lang="scss">
|
||||
.visibility-action {
|
||||
margin-top: 9px;
|
||||
|
||||
&__visibility-menu {
|
||||
top: 40px;
|
||||
|
|
|
|||
|
|
@ -1,138 +0,0 @@
|
|||
<template>
|
||||
<div class="visibility-menu" v-if="show" v-click-outside="hidePopover">
|
||||
<h3 class="visibility-menu__title">Sichtbarkeit</h3>
|
||||
<div v-for="schoolClass in schoolClassVisibility" :key="schoolClass.id" class="visibility-menu__item">
|
||||
<checkbox :checked="!schoolClass.hidden"
|
||||
:item="schoolClass"
|
||||
:label="schoolClass.name"
|
||||
v-on:input="updateVisibility"
|
||||
></checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CHANGE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/mutateContentBlock.gql';
|
||||
import UPDATE_OBJECTIVE_GROUP_VISIBILITY_MUTATION from '@/graphql/gql/mutations/updateObjectiveGroupVisibility.gql';
|
||||
import Checkbox from '@/components/Checkbox';
|
||||
import ME_QUERY from '@/graphql/gql/meQuery.gql'
|
||||
|
||||
export default {
|
||||
props: ['show', 'block'],
|
||||
|
||||
components: {
|
||||
Checkbox
|
||||
},
|
||||
|
||||
apollo: {
|
||||
me: {
|
||||
query: ME_QUERY,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
me: {}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateVisibility(checked, item) {
|
||||
item.hidden = !checked;
|
||||
|
||||
const visibility = this.schoolClassVisibility.map(g => {
|
||||
return {
|
||||
schoolClassId: g.id,
|
||||
hidden: g.hidden || false
|
||||
}
|
||||
});
|
||||
|
||||
let mutation, variables;
|
||||
const id = this.block.id;
|
||||
|
||||
if (this.isContentBlock) {
|
||||
mutation = CHANGE_CONTENT_BLOCK_MUTATION;
|
||||
variables = {
|
||||
input: {
|
||||
id,
|
||||
contentBlock: {
|
||||
visibility
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mutation = UPDATE_OBJECTIVE_GROUP_VISIBILITY_MUTATION;
|
||||
variables = {
|
||||
input: {
|
||||
id,
|
||||
visibility
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.$apollo.mutate({
|
||||
mutation,
|
||||
variables
|
||||
});
|
||||
},
|
||||
hidePopover() {
|
||||
this.$emit('hide-me');
|
||||
},
|
||||
isSchoolClassHidden(schoolClass) {
|
||||
return (this.isContentBlock ? this.block.userCreated : !!this.block.owner)
|
||||
? this.block.visibleFor.findIndex(el => el.id === schoolClass.id) === -1
|
||||
: this.block.hiddenFor.findIndex(el => el.id === schoolClass.id) > -1;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
schoolClasses() {
|
||||
return this.$getRidOfEdges(this.me.schoolClasses);
|
||||
},
|
||||
|
||||
isContentBlock() {
|
||||
return this.block.__typename === 'ContentBlockNode';
|
||||
},
|
||||
|
||||
schoolClassVisibility() {
|
||||
return this.schoolClasses.map(schoolClass => {
|
||||
return {
|
||||
...schoolClass,
|
||||
hidden: this.isSchoolClassHidden(schoolClass)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/styles/_variables.scss";
|
||||
@import "@/styles/_functions.scss";
|
||||
|
||||
.visibility-menu {
|
||||
border-radius: 13px;
|
||||
border: 1px solid $color-silver-light;
|
||||
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.15);
|
||||
width: 180px;
|
||||
box-sizing: border-box;
|
||||
padding: 19px;
|
||||
left: -130px;
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
background-color: $color-white;
|
||||
|
||||
&__title {
|
||||
font-size: toRem(19px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
margin-bottom: 18px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<module :module="module" v-if="module.id"></module>
|
||||
<module :module="module" v-if="module.id" :edit="editModule"></module>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -21,7 +21,8 @@
|
|||
computed: {
|
||||
...mapGetters({
|
||||
scrollToAssignmentId: 'scrollToAssignmentId',
|
||||
isScrollingToAssignment: 'scrollingToAssignment'
|
||||
isScrollingToAssignment: 'scrollingToAssignment',
|
||||
editModule: 'editModule'
|
||||
}),
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ export default new Vuex.Store({
|
|||
vimeoId: null,
|
||||
scrollToAssignmentId: '',
|
||||
scrollToAssignmentReady: false,
|
||||
scrollingToAssignment: false
|
||||
scrollingToAssignment: false,
|
||||
editModule: false
|
||||
},
|
||||
|
||||
getters: {
|
||||
|
|
@ -43,6 +44,7 @@ export default new Vuex.Store({
|
|||
scrollToAssignmentReady: state => state.scrollToAssignmentReady,
|
||||
scrollingToAssignment: state => state.scrollingToAssignment,
|
||||
currentProjectEntry: state => state.currentProjectEntry,
|
||||
editModule: state => state.editModule
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
|
@ -147,6 +149,9 @@ export default new Vuex.Store({
|
|||
commit('setScrollingToAssignment', false);
|
||||
dispatch('scrollToAssignmentId', '');
|
||||
}
|
||||
},
|
||||
editModule({commit}, payload) {
|
||||
commit('setEditModule', payload)
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -213,6 +218,9 @@ export default new Vuex.Store({
|
|||
},
|
||||
setScrollingToAssignment(state, payload) {
|
||||
state.scrollingToAssignment = payload;
|
||||
},
|
||||
setEditModule(state, payload) {
|
||||
state.editModule = payload;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
.action-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: 30px;
|
||||
fill: $color-silver-dark;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue