Merged in feature/objectives-by-user (pull request #10)
Feature/objectives by user
This commit is contained in:
commit
58d42e2472
|
|
@ -2,20 +2,13 @@
|
||||||
<div class="content-block__container">
|
<div class="content-block__container">
|
||||||
<div class="content-block" :class="specialClass">
|
<div class="content-block" :class="specialClass">
|
||||||
<div class="content-block__actions">
|
<div class="content-block__actions">
|
||||||
<a @click="toggleVisibility()" v-if="canManageContent" class="content-block__action-button">
|
<visibility-action
|
||||||
<eye-icon class="content-block__action-icon"></eye-icon>
|
:block="contentBlock"></visibility-action>
|
||||||
</a>
|
|
||||||
<visibility-popover
|
|
||||||
@hide-me="showVisibility = false"
|
|
||||||
:show="showVisibility"
|
|
||||||
:content-block="contentBlock"
|
|
||||||
class="content-block__visibility-menu"
|
|
||||||
></visibility-popover>
|
|
||||||
<a @click="editContentBlock()" v-if="contentBlock.mine" class="content-block__action-button">
|
<a @click="editContentBlock()" v-if="contentBlock.mine" class="content-block__action-button">
|
||||||
<pen-icon class="content-block__action-icon"></pen-icon>
|
<pen-icon class="content-block__action-icon action-icon"></pen-icon>
|
||||||
</a>
|
</a>
|
||||||
<a @click="deleteContentBlock(contentBlock.id)" v-if="contentBlock.mine" class="content-block__action-button">
|
<a @click="deleteContentBlock(contentBlock.id)" v-if="contentBlock.mine" class="content-block__action-button">
|
||||||
<trash-icon class="content-block__action-icon"></trash-icon>
|
<trash-icon class="content-block__action-icon action-icon"></trash-icon>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -46,11 +39,11 @@
|
||||||
import DocumentBlock from '@/components/content-blocks/DocumentBlock';
|
import DocumentBlock from '@/components/content-blocks/DocumentBlock';
|
||||||
import Assignment from '@/components/content-blocks/assignment/Assignment';
|
import Assignment from '@/components/content-blocks/assignment/Assignment';
|
||||||
import AddContentBlockButton from '@/components/AddContentBlockButton';
|
import AddContentBlockButton from '@/components/AddContentBlockButton';
|
||||||
import VisibilityPopover from '@/components/VisibilityPopover';
|
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
||||||
import EyeIcon from '@/components/icons/EyeIcon';
|
import EyeIcon from '@/components/icons/EyeIcon';
|
||||||
import PenIcon from '@/components/icons/PenIcon';
|
import PenIcon from '@/components/icons/PenIcon';
|
||||||
import TrashIcon from '@/components/icons/TrashIcon';
|
import TrashIcon from '@/components/icons/TrashIcon';
|
||||||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
|
||||||
import CHAPTER_QUERY from '@/graphql/gql/chapterQuery.gql';
|
import CHAPTER_QUERY from '@/graphql/gql/chapterQuery.gql';
|
||||||
import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';
|
import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';
|
||||||
|
|
||||||
|
|
@ -68,7 +61,7 @@
|
||||||
Assignment,
|
Assignment,
|
||||||
Task,
|
Task,
|
||||||
AddContentBlockButton,
|
AddContentBlockButton,
|
||||||
VisibilityPopover,
|
VisibilityAction,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
PenIcon,
|
PenIcon,
|
||||||
TrashIcon
|
TrashIcon
|
||||||
|
|
@ -77,16 +70,10 @@
|
||||||
computed: {
|
computed: {
|
||||||
specialClass() {
|
specialClass() {
|
||||||
return `content-block--${this.contentBlock.type.toLowerCase()}`
|
return `content-block--${this.contentBlock.type.toLowerCase()}`
|
||||||
},
|
|
||||||
canManageContent() {
|
|
||||||
return this.me.permissions.includes('users.can_manage_school_class_content');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
toggleVisibility() {
|
|
||||||
this.showVisibility = !this.showVisibility;
|
|
||||||
},
|
|
||||||
editContentBlock() {
|
editContentBlock() {
|
||||||
this.$store.dispatch('editContentBlock', this.contentBlock.id);
|
this.$store.dispatch('editContentBlock', this.contentBlock.id);
|
||||||
},
|
},
|
||||||
|
|
@ -118,18 +105,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
apollo: {
|
|
||||||
me: {
|
|
||||||
query: ME_QUERY,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showVisibility: false,
|
showVisibility: false
|
||||||
me: {
|
|
||||||
permissions: []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -158,16 +136,6 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__action-icon {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
fill: $color-grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__visibility-menu {
|
|
||||||
top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--base_communication {
|
&--base_communication {
|
||||||
@include content-box($color-accent-1);
|
@include content-box($color-accent-1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,30 @@
|
||||||
<div class="module__intro" v-html="module.intro"></div>
|
<div class="module__intro" v-html="module.intro"></div>
|
||||||
|
|
||||||
<h3 id="objectives">Lernziele</h3>
|
<h3 id="objectives">Lernziele</h3>
|
||||||
<objective-group v-for="group in module.objectiveGroups" :key="group.id" :group="group"></objective-group>
|
|
||||||
|
<objective-groups :groups="languageCommunicationObjectiveGroups"></objective-groups>
|
||||||
|
<objective-groups :groups="societyObjectiveGroups"></objective-groups>
|
||||||
|
|
||||||
<chapter :chapter="chapter" :index="index" v-for="(chapter, index) in module.chapters" :key="chapter.id"></chapter>
|
<chapter :chapter="chapter" :index="index" v-for="(chapter, index) in module.chapters" :key="chapter.id"></chapter>
|
||||||
<h3 id="objectives-confirm">Alles klar?</h3>
|
<h3 id="objectives-confirm">Alles klar?</h3>
|
||||||
<objective-group-control
|
|
||||||
v-for="(group, index) in module.objectiveGroups"
|
<objective-groups @updateObjectiveProgress="updateObjectiveProgress" :groups="languageCommunicationObjectiveGroups" :control="true"></objective-groups>
|
||||||
:key="`${group.id}${index}`"
|
<objective-groups @updateObjectiveProgress="updateObjectiveProgress" :groups="societyObjectiveGroups" :control="true"></objective-groups>
|
||||||
:group="group"
|
|
||||||
@updateObjectiveProgress="updateObjectiveProgress"></objective-group-control>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ObjectiveGroup from '@/components/modules/ObjectiveGroup.vue';
|
import ObjectiveGroups from '@/components/modules/ObjectiveGroups.vue';
|
||||||
import ObjectiveGroupControl from '@/components/modules/ObjectiveGroupControl.vue';
|
import ObjectiveGroupControl from '@/components/modules/ObjectiveGroupControl.vue';
|
||||||
import Chapter from '@/components/Chapter.vue';
|
import Chapter from '@/components/Chapter.vue';
|
||||||
import UPDATE_OBJECTIVE_PROGRESS_MUTATION from '@/graphql/gql/mutations/updateObjectiveProgress.gql';
|
import UPDATE_OBJECTIVE_PROGRESS_MUTATION from '@/graphql/gql/mutations/updateObjectiveProgress.gql';
|
||||||
import OBJECTIVE_QUERY from '@/graphql/gql/objectiveQuery.gql';
|
import OBJECTIVE_QUERY from '@/graphql/gql/objectiveQuery.gql';
|
||||||
|
|
||||||
|
const withoutOwnerFirst = (a, b) => a.owner ? 1 : 0;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ObjectiveGroup,
|
ObjectiveGroups,
|
||||||
ObjectiveGroupControl,
|
ObjectiveGroupControl,
|
||||||
Chapter
|
Chapter
|
||||||
},
|
},
|
||||||
|
|
@ -41,15 +43,20 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
created() {
|
||||||
return {
|
|
||||||
chapter: {
|
|
||||||
title: '1.1 Lehrbeginn'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
computed: {
|
||||||
|
languageCommunicationObjectiveGroups() {
|
||||||
|
return this.module.objectiveGroups ? this.module.objectiveGroups
|
||||||
|
.filter(group => group.title === 'LANGUAGE_COMMUNICATION')
|
||||||
|
.sort(withoutOwnerFirst) : [];
|
||||||
|
},
|
||||||
|
societyObjectiveGroups() {
|
||||||
|
return this.module.objectiveGroups ? this.module.objectiveGroups
|
||||||
|
.filter(group => group.title === 'SOCIETY')
|
||||||
|
.sort(withoutOwnerFirst) : [];
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="objective-group">
|
<div class="objective-group">
|
||||||
<h4>{{group.title}}</h4>
|
<div class="objective-group__actions">
|
||||||
|
<visibility-action :block="group">
|
||||||
|
</visibility-action>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>{{group.displayTitle}}</h4>
|
||||||
|
|
||||||
<ul class="objective-group__objective-list">
|
<ul class="objective-group__objective-list">
|
||||||
<li class="objective-group__objective" v-for="objective in group.objectives" :key="objective.id">
|
<li class="objective-group__objective" v-for="objective in group.objectives" :key="objective.id">
|
||||||
|
|
@ -12,9 +17,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
||||||
name: 'objective-group',
|
import EyeIcon from '@/components/icons/EyeIcon';
|
||||||
|
|
||||||
|
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||||
|
|
||||||
|
export default {
|
||||||
props: {
|
props: {
|
||||||
group: {
|
group: {
|
||||||
required: true,
|
required: true,
|
||||||
|
|
@ -22,7 +30,35 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
VisibilityAction,
|
||||||
|
EyeIcon
|
||||||
|
},
|
||||||
|
|
||||||
|
apollo: {
|
||||||
|
me: {
|
||||||
|
query: ME_QUERY,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
canManageContent() {
|
||||||
|
return this.me.permissions.includes('users.can_manage_school_class_content');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.objective-group {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__actions {
|
||||||
|
position: absolute;
|
||||||
|
left: -70px;
|
||||||
|
top: -4px;
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="objective-group objective-group-control">
|
<div class="objective-group objective-group-control">
|
||||||
<h4>{{group.title}}</h4>
|
<h4>{{group.displayTitle}}</h4>
|
||||||
|
|
||||||
<ul class="objective-group__objective-list objective-group__objective-list--no-list">
|
<ul class="objective-group__objective-list objective-group__objective-list--no-list">
|
||||||
<li v-if="objectives" class="objective-group__objective" v-for="objective in objectives" :key="objective.id">
|
<li v-if="objectives" class="objective-group__objective" v-for="objective in objectives" :key="objective.id">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<template v-if="control">
|
||||||
|
<objective-group-control
|
||||||
|
v-for="(group, index) in objectiveGroups"
|
||||||
|
:key="`${group.id}${index}`"
|
||||||
|
:group="group"
|
||||||
|
@updateObjectiveProgress="updateObjectiveProgress"></objective-group-control>
|
||||||
|
</template>
|
||||||
|
<template v-if="!control">
|
||||||
|
<objective-group v-for="group in objectiveGroups" :key="group.id" :group="group"></objective-group>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ObjectiveGroup from '@/components/modules/ObjectiveGroup';
|
||||||
|
import ObjectiveGroupControl from '@/components/modules/ObjectiveGroupControl';
|
||||||
|
import {meQuery} from '@/graphql/queries';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
groups: Array,
|
||||||
|
control: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
ObjectiveGroup,
|
||||||
|
ObjectiveGroupControl
|
||||||
|
},
|
||||||
|
|
||||||
|
apollo: {
|
||||||
|
me: meQuery
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
me: {
|
||||||
|
permissions: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
objectiveGroups() {
|
||||||
|
/*
|
||||||
|
a teacher should get multiple blocks, so he can manage the visibility for his students.
|
||||||
|
students don't care about the blocks, so they should get just one block that contains all the objectives
|
||||||
|
*/
|
||||||
|
if (this.me.permissions.includes('users.can_manage_school_class_content') || !this.groups.length) {
|
||||||
|
return this.groups;
|
||||||
|
} else {
|
||||||
|
// todo: maybe this can be done a bit more elegantly
|
||||||
|
const groups = [...this.groups];
|
||||||
|
const objectives = groups.map(g => g.objectives).flat(); // get all objectives in one array
|
||||||
|
const firstGroup = Object.assign({}, groups.shift(), {objectives});
|
||||||
|
|
||||||
|
return [firstGroup];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
updateObjectiveProgress(checked, id) {
|
||||||
|
this.$emit('updateObjectiveProgress', checked, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
<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>
|
||||||
|
</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 ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['block'],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
VisibilityPopover,
|
||||||
|
EyeIcon
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
canManageContent() {
|
||||||
|
return this.me.permissions.includes('users.can_manage_school_class_content');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
toggleVisibility() {
|
||||||
|
this.showVisibility = !this.showVisibility;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
apollo: {
|
||||||
|
me: {
|
||||||
|
query: ME_QUERY,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showVisibility: false,
|
||||||
|
me: {
|
||||||
|
permissions: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.visibility-action {
|
||||||
|
|
||||||
|
&__visibility-menu {
|
||||||
|
top: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -13,14 +13,12 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CHANGE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/mutateContentBlock.gql';
|
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 Checkbox from '@/components/Checkbox';
|
||||||
import ME_QUERY from '@/graphql/gql/meQuery.gql'
|
import ME_QUERY from '@/graphql/gql/meQuery.gql'
|
||||||
// import MODULE_DETAILS_QUERY from '@/graphql/gql/moduleDetailsQuery.gql';
|
|
||||||
|
|
||||||
// import store from '@/store/index';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['show', 'content-block'],
|
props: ['show', 'block'],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
Checkbox
|
Checkbox
|
||||||
|
|
@ -42,30 +40,48 @@
|
||||||
updateVisibility(checked, item) {
|
updateVisibility(checked, item) {
|
||||||
item.hidden = !checked;
|
item.hidden = !checked;
|
||||||
|
|
||||||
this.$apollo.mutate({
|
const visibility = this.schoolClassVisibility.map(g => {
|
||||||
mutation: CHANGE_CONTENT_BLOCK_MUTATION,
|
return {
|
||||||
variables: {
|
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: {
|
input: {
|
||||||
id: this.contentBlock.id,
|
id,
|
||||||
contentBlock: {
|
contentBlock: {
|
||||||
visibility: this.schoolClassVisibility.map(g => {
|
visibility
|
||||||
return {
|
|
||||||
schoolClassId: g.id,
|
|
||||||
hidden: g.hidden || false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
mutation = UPDATE_OBJECTIVE_GROUP_VISIBILITY_MUTATION;
|
||||||
|
variables = {
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
visibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$apollo.mutate({
|
||||||
|
mutation,
|
||||||
|
variables
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
hidePopover() {
|
hidePopover() {
|
||||||
this.$emit('hide-me');
|
this.$emit('hide-me');
|
||||||
},
|
},
|
||||||
isSchoolClassHidden(schoolClass) {
|
isSchoolClassHidden(schoolClass) {
|
||||||
return this.contentBlock.userCreated
|
return (this.isContentBlock ? this.block.userCreated : !!this.block.owner)
|
||||||
? this.contentBlock.visibleFor.findIndex(el => el.id === schoolClass.id) === -1
|
? this.block.visibleFor.findIndex(el => el.id === schoolClass.id) === -1
|
||||||
: this.contentBlock.hiddenFor.findIndex(el => el.id === schoolClass.id) > -1;
|
: this.block.hiddenFor.findIndex(el => el.id === schoolClass.id) > -1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -74,6 +90,10 @@
|
||||||
return this.$getRidOfEdges(this.me.schoolClasses);
|
return this.$getRidOfEdges(this.me.schoolClasses);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isContentBlock() {
|
||||||
|
return this.block.__typename === 'ContentBlockNode';
|
||||||
|
},
|
||||||
|
|
||||||
schoolClassVisibility() {
|
schoolClassVisibility() {
|
||||||
return this.schoolClasses.map(schoolClass => {
|
return this.schoolClasses.map(schoolClass => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
fragment ObjectiveGroupParts on ObjectiveGroupNode {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
displayTitle
|
||||||
|
owner {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
hiddenFor {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visibleFor {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#import "./fragments/chapterParts.gql"
|
#import "./fragments/chapterParts.gql"
|
||||||
#import "./fragments/assignmentParts.gql"
|
#import "./fragments/assignmentParts.gql"
|
||||||
|
#import "./fragments/objectiveGroupParts.gql"
|
||||||
query ModulesQuery($slug: String!) {
|
query ModulesQuery($slug: String!) {
|
||||||
module(slug: $slug) {
|
module(slug: $slug) {
|
||||||
id
|
id
|
||||||
|
|
@ -19,8 +20,7 @@ query ModulesQuery($slug: String!) {
|
||||||
objectiveGroups {
|
objectiveGroups {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
id
|
...ObjectiveGroupParts
|
||||||
title
|
|
||||||
objectives {
|
objectives {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#import "../fragments/objectiveGroupParts.gql"
|
||||||
|
mutation UpdateObjectiveGroupVisibility($input: UpdateObjectiveGroupVisibilityInput!) {
|
||||||
|
updateObjectiveGroupVisibility(input: $input) {
|
||||||
|
objectiveGroup {
|
||||||
|
...ObjectiveGroupParts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import MODULE_DETAILS_QUERY from './gql/moduleDetailsQuery.gql';
|
import MODULE_DETAILS_QUERY from './gql/moduleDetailsQuery.gql';
|
||||||
|
import ME_QUERY from './gql/meQuery.gql';
|
||||||
|
|
||||||
export function moduleQuery() {
|
export function moduleQuery() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -11,3 +12,9 @@ export function moduleQuery() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function meQuery() {
|
||||||
|
return {
|
||||||
|
query: ME_QUERY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
.action-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
fill: $color-grey;
|
||||||
|
}
|
||||||
|
|
@ -12,3 +12,4 @@
|
||||||
@import "help-text";
|
@import "help-text";
|
||||||
@import "objective-group";
|
@import "objective-group";
|
||||||
@import "article";
|
@import "article";
|
||||||
|
@import "actions";
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class ContentElementValueInput(InputObjectType):
|
||||||
# we'll handle this with a single input, even tho it would be nice to have a type for every different possibility
|
# we'll handle this with a single input, even tho it would be nice to have a type for every different possibility
|
||||||
# see discussion at https://github.com/graphql/graphql-js/issues/207
|
# see discussion at https://github.com/graphql/graphql-js/issues/207
|
||||||
text = graphene.String(description='To be used for link_block, text_block types')
|
text = graphene.String(description='To be used for link_block, text_block types')
|
||||||
url = graphene.String(description='To be used for link, basic_knowledge, image_block types')
|
url = graphene.String(description='To be used for link, image_block types')
|
||||||
description = graphene.String(description='To be used for basic_knowledge type')
|
description = graphene.String(description='To be used for basic_knowledge type')
|
||||||
title = graphene.String(description='To be used for image_block, assignment type')
|
title = graphene.String(description='To be used for image_block, assignment type')
|
||||||
assignment = graphene.String(description='To be used for assignment type')
|
assignment = graphene.String(description='To be used for assignment type')
|
||||||
|
|
@ -29,7 +29,7 @@ class ContentElementInput(InputObjectType):
|
||||||
value = ContentElementValueInput()
|
value = ContentElementValueInput()
|
||||||
|
|
||||||
|
|
||||||
class UserGroupContentBlockVisibility(InputObjectType):
|
class UserGroupBlockVisibility(InputObjectType):
|
||||||
school_class_id = graphene.ID(required=True)
|
school_class_id = graphene.ID(required=True)
|
||||||
hidden = graphene.Boolean(required=True)
|
hidden = graphene.Boolean(required=True)
|
||||||
|
|
||||||
|
|
@ -38,4 +38,4 @@ class ContentBlockInput(InputObjectType):
|
||||||
title = graphene.String()
|
title = graphene.String()
|
||||||
type = graphene.String()
|
type = graphene.String()
|
||||||
contents = graphene.List(ContentElementInput)
|
contents = graphene.List(ContentElementInput)
|
||||||
visibility = graphene.List(UserGroupContentBlockVisibility)
|
visibility = graphene.List(UserGroupBlockVisibility)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ from api.utils import get_object, get_errors
|
||||||
from books.models import ContentBlock, Chapter, SchoolClass
|
from books.models import ContentBlock, Chapter, SchoolClass
|
||||||
from books.schema.inputs import ContentBlockInput
|
from books.schema.inputs import ContentBlockInput
|
||||||
from books.schema.queries import ContentBlockNode
|
from books.schema.queries import ContentBlockNode
|
||||||
|
from core.utils import set_hidden_for, set_visible_for
|
||||||
from .utils import handle_content_block, set_user_defined_block_type
|
from .utils import handle_content_block, set_user_defined_block_type
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,9 +38,9 @@ class MutateContentBlock(relay.ClientIDMutation):
|
||||||
|
|
||||||
if visibility_list is not None:
|
if visibility_list is not None:
|
||||||
if content_block.user_created:
|
if content_block.user_created:
|
||||||
cls.set_visible_for(content_block, visibility_list)
|
set_visible_for(content_block, visibility_list)
|
||||||
else:
|
else:
|
||||||
cls.set_hidden_for(content_block, visibility_list)
|
set_hidden_for(content_block, visibility_list)
|
||||||
|
|
||||||
if title is not None:
|
if title is not None:
|
||||||
content_block.title = title
|
content_block.title = title
|
||||||
|
|
@ -59,24 +60,6 @@ class MutateContentBlock(relay.ClientIDMutation):
|
||||||
|
|
||||||
return cls(content_block=None, errors=errors)
|
return cls(content_block=None, errors=errors)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def set_hidden_for(cls, content_block, visibility_list):
|
|
||||||
for v in visibility_list:
|
|
||||||
school_class = get_object(SchoolClass, v.school_class_id)
|
|
||||||
if v.hidden:
|
|
||||||
content_block.hidden_for.add(school_class)
|
|
||||||
else:
|
|
||||||
content_block.hidden_for.remove(school_class)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def set_visible_for(cls, content_block, visibility_list):
|
|
||||||
for v in visibility_list:
|
|
||||||
school_class = get_object(SchoolClass, v.school_class_id)
|
|
||||||
if v.hidden:
|
|
||||||
content_block.visible_for.remove(school_class)
|
|
||||||
else:
|
|
||||||
content_block.visible_for.add(school_class)
|
|
||||||
|
|
||||||
|
|
||||||
class AddContentBlock(relay.ClientIDMutation):
|
class AddContentBlock(relay.ClientIDMutation):
|
||||||
class Input:
|
class Input:
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,6 @@ class ChapterNode(DjangoObjectType):
|
||||||
|
|
||||||
return publisher_content_blocks.union(user_created_content_blocks)
|
return publisher_content_blocks.union(user_created_content_blocks)
|
||||||
|
|
||||||
# if user.has_perm('users.can_manage_school_class_content'):
|
|
||||||
# return ContentBlock.get_by_parent(self)
|
|
||||||
# else:
|
|
||||||
# return ContentBlock.get_by_parent(self)
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleNode(DjangoObjectType):
|
class ModuleNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
|
|
@ -88,6 +83,22 @@ class ModuleNode(DjangoObjectType):
|
||||||
def resolve_chapters(self, info, **kwargs):
|
def resolve_chapters(self, info, **kwargs):
|
||||||
return Chapter.get_by_parent(self)
|
return Chapter.get_by_parent(self)
|
||||||
|
|
||||||
|
def resolve_objective_groups(self, info, **kwargs):
|
||||||
|
user = info.context.user
|
||||||
|
school_classes = user.school_classes.values_list('pk')
|
||||||
|
|
||||||
|
if user.has_perm('users.can_manage_school_class_content'): # teacher
|
||||||
|
publisher_objective_groups = self.objective_groups.filter(owner=None)
|
||||||
|
user_created_objective_groups = self.objective_groups.filter(owner=user)
|
||||||
|
else: # student
|
||||||
|
publisher_objective_groups = self.objective_groups.filter(owner=None).exclude(
|
||||||
|
hidden_for__in=school_classes)
|
||||||
|
|
||||||
|
user_created_objective_groups = self.objective_groups.filter(owner__isnull=False,
|
||||||
|
visible_for__in=school_classes)
|
||||||
|
|
||||||
|
return publisher_objective_groups.union(user_created_objective_groups)
|
||||||
|
|
||||||
|
|
||||||
class TopicNode(DjangoObjectType):
|
class TopicNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ from users.services import create_users
|
||||||
|
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
'title': 'Gesellschaft',
|
'title': 'society',
|
||||||
'topics': [
|
'topics': [
|
||||||
{
|
{
|
||||||
'order': 1,
|
'order': 1,
|
||||||
|
|
@ -42,7 +42,7 @@ data = [
|
||||||
""",
|
""",
|
||||||
'objective_groups': [
|
'objective_groups': [
|
||||||
{
|
{
|
||||||
'title': 'Gesellschaft',
|
'title': 'society',
|
||||||
'objectives': [
|
'objectives': [
|
||||||
{
|
{
|
||||||
'text': 'Ich kann wichtige personelle und organisatorische Strukturen der Berufsfachschule beschreiben und deren Angebote, Konzepte erklären und Weisungen nennen.'
|
'text': 'Ich kann wichtige personelle und organisatorische Strukturen der Berufsfachschule beschreiben und deren Angebote, Konzepte erklären und Weisungen nennen.'
|
||||||
|
|
@ -56,7 +56,7 @@ data = [
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Sprache und Kommunikation',
|
'title': 'language_communication',
|
||||||
'objectives': [
|
'objectives': [
|
||||||
{
|
{
|
||||||
'text': 'Ich kenne verschiedene Arten von Fragen.'
|
'text': 'Ich kenne verschiedene Arten von Fragen.'
|
||||||
|
|
@ -348,7 +348,7 @@ data = [
|
||||||
""",
|
""",
|
||||||
'objective_groups': [
|
'objective_groups': [
|
||||||
{
|
{
|
||||||
'title': 'Gesellschaft',
|
'title': 'society',
|
||||||
'objectives': [
|
'objectives': [
|
||||||
{
|
{
|
||||||
'text': 'Ich kann Anlageformen für mich so auswählen, dass sie meiner wirtschaftlichen Situation und meiner Risikofreude entsprechen.'
|
'text': 'Ich kann Anlageformen für mich so auswählen, dass sie meiner wirtschaftlichen Situation und meiner Risikofreude entsprechen.'
|
||||||
|
|
@ -359,7 +359,7 @@ data = [
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Sprache und Kommunikation',
|
'title': 'language_communication',
|
||||||
'objectives': [
|
'objectives': [
|
||||||
{
|
{
|
||||||
'text': 'Ich kann zu wichtigen Aussagen aus einem Erklärvideo Notizen machen.'
|
'text': 'Ich kann zu wichtigen Aussagen aus einem Erklärvideo Notizen machen.'
|
||||||
|
|
@ -755,7 +755,7 @@ class Command(BaseCommand):
|
||||||
for objective_group_idx, objective_group_entry in enumerate(objective_group_data):
|
for objective_group_idx, objective_group_entry in enumerate(objective_group_data):
|
||||||
factory_params = self.filter_data(objective_group_entry, 'objectives')
|
factory_params = self.filter_data(objective_group_entry, 'objectives')
|
||||||
objective_group = ObjectiveGroupFactory.create(module=module,
|
objective_group = ObjectiveGroupFactory.create(module=module,
|
||||||
user=None,
|
owner=None,
|
||||||
**factory_params)
|
**factory_params)
|
||||||
|
|
||||||
default_objectives = [{} for i in range(0, 4)]
|
default_objectives = [{} for i in range(0, 4)]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
from api.utils import get_object
|
||||||
|
from users.models import SchoolClass
|
||||||
|
|
||||||
|
|
||||||
|
def set_hidden_for(block, visibility_list):
|
||||||
|
for v in visibility_list:
|
||||||
|
school_class = get_object(SchoolClass, v.school_class_id)
|
||||||
|
if v.hidden:
|
||||||
|
block.hidden_for.add(school_class)
|
||||||
|
else:
|
||||||
|
block.hidden_for.remove(school_class)
|
||||||
|
|
||||||
|
|
||||||
|
def set_visible_for(block, visibility_list):
|
||||||
|
for v in visibility_list:
|
||||||
|
school_class = get_object(SchoolClass, v.school_class_id)
|
||||||
|
if v.hidden:
|
||||||
|
block.visible_for.remove(school_class)
|
||||||
|
else:
|
||||||
|
block.visible_for.add(school_class)
|
||||||
|
|
@ -5,8 +5,8 @@ from objectives.models import ObjectiveGroup, Objective, ObjectiveProgressStatus
|
||||||
|
|
||||||
@admin.register(ObjectiveGroup)
|
@admin.register(ObjectiveGroup)
|
||||||
class ObjectiveGroupAdmin(admin.ModelAdmin):
|
class ObjectiveGroupAdmin(admin.ModelAdmin):
|
||||||
list_display = ('title', 'module', 'user')
|
list_display = ('title', 'module', 'owner')
|
||||||
list_filter = ('title', 'module', 'user')
|
list_filter = ('title', 'module', 'owner')
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Objective)
|
@admin.register(Objective)
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ class ObjectiveGroupFactory(factory.django.DjangoModelFactory):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ObjectiveGroup
|
model = ObjectiveGroup
|
||||||
|
|
||||||
title = factory.Iterator(['Gesellschaft', 'Sprache und Kommunikation'])
|
title = factory.Iterator([ObjectiveGroup.LANGUAGE_COMMUNICATION, ObjectiveGroup.SOCIETY])
|
||||||
|
|
||||||
module = factory.SubFactory(ModuleFactory)
|
module = factory.SubFactory(ModuleFactory)
|
||||||
user = factory.Iterator(get_user_model().objects.all())
|
owner = factory.Iterator(get_user_model().objects.all())
|
||||||
|
|
||||||
|
|
||||||
class ObjectiveFactory(factory.django.DjangoModelFactory):
|
class ObjectiveFactory(factory.django.DjangoModelFactory):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.0.6 on 2018-10-30 17:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('objectives', '0003_auto_20181022_1646'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='objectivegroup',
|
||||||
|
name='title',
|
||||||
|
field=models.CharField(blank=True, choices=[('language_communication', 'Sprache & Kommunikation'), ('society', 'Gesellschaft')], default='language_communication', max_length=255, verbose_name='title'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_titles(apps, schema_editor):
|
||||||
|
ObjectiveGroup = apps.get_model('objectives', 'ObjectiveGroup')
|
||||||
|
for og in ObjectiveGroup.objects.filter(title='Sprache und Kommunikation'):
|
||||||
|
og.title = 'language_communication'
|
||||||
|
og.save()
|
||||||
|
for og in ObjectiveGroup.objects.filter(title='Gesellschaft'):
|
||||||
|
og.title = 'society'
|
||||||
|
og.save()
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('objectives', '0004_auto_20181030_1726')
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(migrate_titles)
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Generated by Django 2.0.6 on 2018-10-31 13:23
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0002_auto_20181017_1340'),
|
||||||
|
('objectives', '0005_migrate_titles'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='objectivegroup',
|
||||||
|
old_name='user',
|
||||||
|
new_name='owner',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='objectivegroup',
|
||||||
|
name='hidden_for',
|
||||||
|
field=models.ManyToManyField(related_name='hidden_objective_groups', to='users.SchoolClass'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='objectivegroup',
|
||||||
|
name='visible_for',
|
||||||
|
field=models.ManyToManyField(related_name='visible_objective_groups', to='users.SchoolClass'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 2.0.6 on 2018-10-31 13:47
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('objectives', '0006_auto_20181031_1323'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='objectivegroup',
|
||||||
|
name='hidden_for',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='hidden_objective_groups', to='users.SchoolClass'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='objectivegroup',
|
||||||
|
name='visible_for',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='visible_objective_groups', to='users.SchoolClass'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -2,6 +2,7 @@ from django.contrib.auth import get_user_model
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from books.models import Module
|
from books.models import Module
|
||||||
|
from users.models import SchoolClass
|
||||||
|
|
||||||
|
|
||||||
class ObjectiveGroup(models.Model):
|
class ObjectiveGroup(models.Model):
|
||||||
|
|
@ -9,10 +10,21 @@ class ObjectiveGroup(models.Model):
|
||||||
verbose_name = 'Lernzielgruppe'
|
verbose_name = 'Lernzielgruppe'
|
||||||
verbose_name_plural = 'Lernzielgruppen'
|
verbose_name_plural = 'Lernzielgruppen'
|
||||||
|
|
||||||
title = models.CharField('title', blank=True, null=False, max_length=255)
|
LANGUAGE_COMMUNICATION = 'language_communication'
|
||||||
|
SOCIETY = 'society'
|
||||||
|
|
||||||
|
TITLE_CHOICES = (
|
||||||
|
(LANGUAGE_COMMUNICATION, 'Sprache & Kommunikation'),
|
||||||
|
(SOCIETY, 'Gesellschaft'),
|
||||||
|
)
|
||||||
|
|
||||||
|
title = models.CharField('title', blank=True, null=False, max_length=255, choices=TITLE_CHOICES, default=LANGUAGE_COMMUNICATION)
|
||||||
module = models.ForeignKey(Module, blank=False, null=False, on_delete=models.CASCADE, related_name='objective_groups')
|
module = models.ForeignKey(Module, blank=False, null=False, on_delete=models.CASCADE, related_name='objective_groups')
|
||||||
# a user can define her own objectives, hence this optional param
|
# a user can define her own objectives, hence this optional param
|
||||||
user = models.ForeignKey(get_user_model(), blank=True, null=True, on_delete=models.CASCADE)
|
owner = models.ForeignKey(get_user_model(), blank=True, null=True, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
hidden_for = models.ManyToManyField(SchoolClass, related_name='hidden_objective_groups', blank=True)
|
||||||
|
visible_for = models.ManyToManyField(SchoolClass, related_name='visible_objective_groups', blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'ObjectiveGroup {}-{}-{}'.format(self.id, self.module, self.title)
|
return 'ObjectiveGroup {}-{}-{}'.format(self.id, self.module, self.title)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import relay
|
from graphene import relay, InputObjectType
|
||||||
from api.utils import get_object
|
from api.utils import get_object
|
||||||
from objectives.models import ObjectiveProgressStatus, Objective
|
from books.schema.inputs import UserGroupBlockVisibility
|
||||||
from objectives.schema import ObjectiveNode
|
from core.utils import set_visible_for, set_hidden_for
|
||||||
|
from objectives.models import ObjectiveProgressStatus, Objective, ObjectiveGroup
|
||||||
|
from objectives.schema import ObjectiveNode, ObjectiveGroupNode
|
||||||
|
|
||||||
|
|
||||||
class UpdateObjectiveProgress(relay.ClientIDMutation):
|
class UpdateObjectiveProgress(relay.ClientIDMutation):
|
||||||
|
|
@ -29,5 +31,31 @@ class UpdateObjectiveProgress(relay.ClientIDMutation):
|
||||||
return cls(objective=objective)
|
return cls(objective=objective)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateObjectiveGroupVisibility(relay.ClientIDMutation):
|
||||||
|
class Input:
|
||||||
|
id = graphene.ID(required=True, description='The ID of the objective group')
|
||||||
|
visibility = graphene.List(UserGroupBlockVisibility)
|
||||||
|
|
||||||
|
objective_group = graphene.Field(ObjectiveGroupNode)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
||||||
|
objective_group_id = kwargs.get('id')
|
||||||
|
visibility_list = kwargs.get('visibility')
|
||||||
|
objective_group = get_object(ObjectiveGroup, objective_group_id) # info.context.user = django user
|
||||||
|
|
||||||
|
if visibility_list is not None:
|
||||||
|
if objective_group.owner is not None:
|
||||||
|
set_visible_for(objective_group, visibility_list)
|
||||||
|
else:
|
||||||
|
set_hidden_for(objective_group, visibility_list)
|
||||||
|
|
||||||
|
objective_group.save()
|
||||||
|
|
||||||
|
|
||||||
|
return cls(objective_group=objective_group)
|
||||||
|
|
||||||
|
|
||||||
class ObjectiveMutations:
|
class ObjectiveMutations:
|
||||||
update_objective_progress = UpdateObjectiveProgress.Field()
|
update_objective_progress = UpdateObjectiveProgress.Field()
|
||||||
|
update_objective_group_visibility = UpdateObjectiveGroupVisibility.Field()
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from objectives.models import ObjectiveGroup, Objective, ObjectiveProgressStatus
|
||||||
|
|
||||||
class ObjectiveGroupNode(DjangoObjectType):
|
class ObjectiveGroupNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
|
display_title = graphene.String()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ObjectiveGroup
|
model = ObjectiveGroup
|
||||||
|
|
@ -17,6 +18,10 @@ class ObjectiveGroupNode(DjangoObjectType):
|
||||||
def resolve_pk(self, *args, **kwargs):
|
def resolve_pk(self, *args, **kwargs):
|
||||||
return self.id
|
return self.id
|
||||||
|
|
||||||
|
def resolve_display_title(self, *args, **kwargs):
|
||||||
|
return self.get_title_display()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectiveNode(DjangoObjectType):
|
class ObjectiveNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
|
|
@ -26,6 +31,9 @@ class ObjectiveNode(DjangoObjectType):
|
||||||
filter_fields = ['text']
|
filter_fields = ['text']
|
||||||
interfaces = (relay.Node,)
|
interfaces = (relay.Node,)
|
||||||
|
|
||||||
|
def resolve_objective_progress(self, info, **kwargs):
|
||||||
|
return self.objective_progress.filter(user=info.context.user)
|
||||||
|
|
||||||
|
|
||||||
class ObjectiveProgressStatusNode(DjangoObjectType):
|
class ObjectiveProgressStatusNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
|
|
@ -40,4 +48,5 @@ class ObjectiveProgressStatusNode(DjangoObjectType):
|
||||||
|
|
||||||
|
|
||||||
class ObjectivesQuery(object):
|
class ObjectivesQuery(object):
|
||||||
|
objective_group = relay.Node.Field(ObjectiveGroupNode)
|
||||||
objective_groups = DjangoFilterConnectionField(ObjectiveGroupNode)
|
objective_groups = DjangoFilterConnectionField(ObjectiveGroupNode)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue