Enable teachers to add new objectives instead of objective groups
This commit is contained in:
parent
76b3f70a87
commit
6d5fa1806d
|
|
@ -21,6 +21,7 @@
|
||||||
import EditObjectiveGroupWizard from '@/components/objective-groups/EditObjectiveGroupWizard';
|
import EditObjectiveGroupWizard from '@/components/objective-groups/EditObjectiveGroupWizard';
|
||||||
import NewProjectEntryWizard from '@/components/portfolio/NewProjectEntryWizard';
|
import NewProjectEntryWizard from '@/components/portfolio/NewProjectEntryWizard';
|
||||||
import EditProjectEntryWizard from '@/components/portfolio/EditProjectEntryWizard';
|
import EditProjectEntryWizard from '@/components/portfolio/EditProjectEntryWizard';
|
||||||
|
import NewObjectiveWizard from '@/components/objective-groups/NewObjectiveWizard';
|
||||||
import FullscreenImage from '@/components/FullscreenImage';
|
import FullscreenImage from '@/components/FullscreenImage';
|
||||||
import FullscreenInfographic from '@/components/FullscreenInfographic';
|
import FullscreenInfographic from '@/components/FullscreenInfographic';
|
||||||
import FullscreenVideo from '@/components/FullscreenVideo';
|
import FullscreenVideo from '@/components/FullscreenVideo';
|
||||||
|
|
@ -41,10 +42,12 @@
|
||||||
EditContentBlockWizard,
|
EditContentBlockWizard,
|
||||||
NewRoomEntryWizard,
|
NewRoomEntryWizard,
|
||||||
EditRoomEntryWizard,
|
EditRoomEntryWizard,
|
||||||
|
// todo: remove
|
||||||
NewObjectiveGroupWizard,
|
NewObjectiveGroupWizard,
|
||||||
EditObjectiveGroupWizard,
|
EditObjectiveGroupWizard,
|
||||||
NewProjectEntryWizard,
|
NewProjectEntryWizard,
|
||||||
EditProjectEntryWizard,
|
EditProjectEntryWizard,
|
||||||
|
NewObjectiveWizard,
|
||||||
FullscreenImage,
|
FullscreenImage,
|
||||||
FullscreenInfographic,
|
FullscreenInfographic,
|
||||||
FullscreenVideo
|
FullscreenVideo
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="add-content">
|
<div class="add-content">
|
||||||
<a class="add-content__button" v-on:click="addContentBlock">
|
<a class="add-content__button" v-on:click="addContent">
|
||||||
<add-pointer class="add-content__icon"></add-pointer>
|
<add-pointer class="add-content__icon"></add-pointer>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -17,11 +17,15 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
addContentBlock() {
|
addContent() {
|
||||||
this.$store.dispatch('addContentBlock', {
|
if (this.parent && this.parent.__typename === 'ObjectiveGroupNode') {
|
||||||
after: this.after,
|
this.$store.dispatch('addObjective', this.parent.id);
|
||||||
parent: this.parent
|
} else {
|
||||||
});
|
this.$store.dispatch('addContentBlock', {
|
||||||
|
after: this.after ? this.after.id : undefined,
|
||||||
|
parent: this.parent ? this.parent.id : undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
{{chapter.description}}
|
{{chapter.description}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<add-content-block-button :parent="chapter.id" v-if="editModule"></add-content-block-button>
|
<add-content-button :parent="chapter" v-if="editModule"></add-content-button>
|
||||||
|
|
||||||
<content-block :contentBlock="contentBlock"
|
<content-block :contentBlock="contentBlock"
|
||||||
:parent="chapter.id"
|
:parent="chapter.id"
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ContentBlock from '@/components/ContentBlock';
|
import ContentBlock from '@/components/ContentBlock';
|
||||||
import AddContentBlockButton from '@/components/AddContentBlockButton';
|
import AddContentButton from '@/components/AddContentButton';
|
||||||
|
|
||||||
import {mapGetters} from 'vuex';
|
import {mapGetters} from 'vuex';
|
||||||
import {isHidden} from '@/helpers/content-block';
|
import {isHidden} from '@/helpers/content-block';
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
ContentBlock,
|
ContentBlock,
|
||||||
AddContentBlockButton
|
AddContentButton
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="content-block__container" :class="{'content-block__container--hidden': hidden}">
|
<div class="content-block__container hideable-element" :class="{'hideable-element--hidden': hidden}">
|
||||||
<div class="content-block" :class="specialClass">
|
<div class="content-block" :class="specialClass">
|
||||||
<div class="content-block__actions" v-if="canEditContentBlock && editModule">
|
<div class="content-block__actions" v-if="canEditContentBlock && editModule">
|
||||||
<user-widget v-bind="me" class="content-block__user-widget"></user-widget>
|
<user-widget v-bind="me" class="content-block__user-widget"></user-widget>
|
||||||
|
|
@ -8,16 +8,10 @@
|
||||||
<li class="popover-links__link"><a @click="editContentBlock(contentBlock)">Bearbeiten</a></li>
|
<li class="popover-links__link"><a @click="editContentBlock(contentBlock)">Bearbeiten</a></li>
|
||||||
</more-options-widget>
|
</more-options-widget>
|
||||||
</div>
|
</div>
|
||||||
<div class="content-block__visibility" v-if="editModule">
|
<div class="content-block__visibility">
|
||||||
<visibility-action
|
<visibility-action
|
||||||
v-if="!contentBlock.indent"
|
v-if="!contentBlock.indent && editModule"
|
||||||
:block="contentBlock"></visibility-action>
|
: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>
|
</div>
|
||||||
|
|
||||||
<h3 v-if="instrumentLabel !== ''" class="content-block__instrument-label">{{instrumentLabel}}</h3>
|
<h3 v-if="instrumentLabel !== ''" class="content-block__instrument-label">{{instrumentLabel}}</h3>
|
||||||
|
|
@ -31,8 +25,8 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<add-content-block-button :after="contentBlock.id"
|
<add-content-button :after="contentBlock"
|
||||||
v-if="!contentBlock.indent && editModule"></add-content-block-button>
|
v-if="!contentBlock.indent && editModule"></add-content-button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -54,7 +48,7 @@
|
||||||
import Assignment from '@/components/content-blocks/assignment/Assignment';
|
import Assignment from '@/components/content-blocks/assignment/Assignment';
|
||||||
import Survey from '@/components/content-blocks/SurveyBlock';
|
import Survey from '@/components/content-blocks/SurveyBlock';
|
||||||
import Solution from '@/components/content-blocks/Solution';
|
import Solution from '@/components/content-blocks/Solution';
|
||||||
import AddContentBlockButton from '@/components/AddContentBlockButton';
|
import AddContentButton from '@/components/AddContentButton';
|
||||||
import MoreOptionsWidget from '@/components/MoreOptionsWidget';
|
import MoreOptionsWidget from '@/components/MoreOptionsWidget';
|
||||||
import UserWidget from '@/components/UserWidget';
|
import UserWidget from '@/components/UserWidget';
|
||||||
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
||||||
|
|
@ -99,7 +93,7 @@
|
||||||
Solution,
|
Solution,
|
||||||
Assignment,
|
Assignment,
|
||||||
Task,
|
Task,
|
||||||
AddContentBlockButton,
|
AddContentButton,
|
||||||
VisibilityAction,
|
VisibilityAction,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
PenIcon,
|
PenIcon,
|
||||||
|
|
@ -249,19 +243,6 @@
|
||||||
|
|
||||||
&__container {
|
&__container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&--hidden {
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
background: rgba(255, 255, 255, 0.5);
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
|
|
@ -273,13 +254,6 @@
|
||||||
@include regular-text();
|
@include regular-text();
|
||||||
}
|
}
|
||||||
|
|
||||||
&__visibility {
|
|
||||||
position: absolute;
|
|
||||||
left: -70px;
|
|
||||||
top: -4px;
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__actions {
|
&__actions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,8 @@
|
||||||
<h3 id="objectives">Lernziele</h3>
|
<h3 id="objectives">Lernziele</h3>
|
||||||
|
|
||||||
<objective-groups :groups="languageCommunicationObjectiveGroups"></objective-groups>
|
<objective-groups :groups="languageCommunicationObjectiveGroups"></objective-groups>
|
||||||
<add-objective-group-button v-if="!isStudent" type="languageCommunication"
|
|
||||||
:module="module.id"></add-objective-group-button>
|
|
||||||
|
|
||||||
<objective-groups :groups="societyObjectiveGroups"></objective-groups>
|
<objective-groups :groups="societyObjectiveGroups"></objective-groups>
|
||||||
<add-objective-group-button v-if="!isStudent" type="society" :module="module.id"></add-objective-group-button>
|
|
||||||
|
|
||||||
<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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
<template>
|
||||||
|
<modal :hide-header="true">
|
||||||
|
<modal-input
|
||||||
|
:placeholder="'Lernziel'"
|
||||||
|
:value="text"
|
||||||
|
@input="text = $event"
|
||||||
|
></modal-input>
|
||||||
|
|
||||||
|
<div slot="footer">
|
||||||
|
<a class="button button--primary" data-cy="modal-save-button" :class="{'button--disabled': disableSave}"
|
||||||
|
v-on:click="save(text)">Speichern</a>
|
||||||
|
<a class="button" v-on:click="hide()">Abbrechen</a>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Modal from '@/components/Modal';
|
||||||
|
import ModalInput from '@/components/ModalInput';
|
||||||
|
|
||||||
|
import NEW_OBJECTIVE_MUTATION from '@/graphql/gql/mutations/addObjective.gql';
|
||||||
|
import OBJECTIVE_GROUP_QUERY from '@/graphql/gql/objectiveGroupQuery.gql';
|
||||||
|
|
||||||
|
import {mapGetters} from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Modal,
|
||||||
|
ModalInput
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
objectiveGroup: 'currentObjectiveGroup'
|
||||||
|
}),
|
||||||
|
disableSave() {
|
||||||
|
return this.saving;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
text: '',
|
||||||
|
saving: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
save(entry) {
|
||||||
|
this.saving = true;
|
||||||
|
this.$apollo.mutate({
|
||||||
|
mutation: NEW_OBJECTIVE_MUTATION,
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
objective: Object.assign({}, {
|
||||||
|
objectiveGroup: this.objectiveGroup,
|
||||||
|
text: entry
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update: (store, {data: {addObjective: {objective}}}) => {
|
||||||
|
try {
|
||||||
|
const query = OBJECTIVE_GROUP_QUERY;
|
||||||
|
const variables = {id: this.objectiveGroup};
|
||||||
|
const data = store.readQuery({query, variables});
|
||||||
|
if (data.objectiveGroup && data.objectiveGroup.objectives) {
|
||||||
|
data.objectiveGroup.objectives.edges.push({
|
||||||
|
node: objective,
|
||||||
|
__typename: 'ObjectiveNode'
|
||||||
|
});
|
||||||
|
store.writeQuery({query, variables, data});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
this.saving = false;
|
||||||
|
this.hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hide() {
|
||||||
|
this.$store.dispatch('hideModal');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -1,21 +1,34 @@
|
||||||
<template>
|
<template>
|
||||||
<li class="objective">
|
<li class="objective hideable-element" :class="{'hideable-element--hidden': hidden}">
|
||||||
<div class="objective__actions">
|
|
||||||
<visibility-action
|
<visibility-action
|
||||||
:block="objective"></visibility-action>
|
v-if="editModule"
|
||||||
|
:block="objective"></visibility-action>
|
||||||
|
<div>
|
||||||
|
{{objective.text}}
|
||||||
</div>
|
</div>
|
||||||
{{objective.text}}
|
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
||||||
|
|
||||||
|
import {mapGetters} from 'vuex';
|
||||||
|
import {isHidden} from '@/helpers/content-block';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['objective'],
|
props: ['objective', 'schoolClass'],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
VisibilityAction
|
VisibilityAction
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['editModule']),
|
||||||
|
hidden() {
|
||||||
|
return isHidden(this.objective, this.schoolClass)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@
|
||||||
|
|
||||||
<ul class="objective-group__objective-list">
|
<ul class="objective-group__objective-list">
|
||||||
<objective class="objective-group__objective" v-for="objective in group.objectives" :key="objective.id"
|
<objective class="objective-group__objective" v-for="objective in group.objectives" :key="objective.id"
|
||||||
:objective="objective">
|
:objective="objective" :school-class="currentFilter">
|
||||||
</objective>
|
</objective>
|
||||||
</ul>
|
</ul>
|
||||||
|
<add-content-button :parent="group">
|
||||||
|
</add-content-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -19,6 +21,7 @@
|
||||||
import PenIcon from '@/components/icons/PenIcon';
|
import PenIcon from '@/components/icons/PenIcon';
|
||||||
|
|
||||||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||||
|
import AddContentButton from '@/components/AddContentButton';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -29,6 +32,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
|
AddContentButton,
|
||||||
VisibilityAction,
|
VisibilityAction,
|
||||||
Objective,
|
Objective,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
|
|
@ -44,7 +48,10 @@
|
||||||
computed: {
|
computed: {
|
||||||
canManageContent() {
|
canManageContent() {
|
||||||
return this.me.permissions.includes('users.can_manage_school_class_content');
|
return this.me.permissions.includes('users.can_manage_school_class_content');
|
||||||
}
|
},
|
||||||
|
currentFilter() {
|
||||||
|
return this.me.selectedClass;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
},
|
},
|
||||||
hidden() {
|
hidden() {
|
||||||
// is this content block / objective group user created?
|
// is this content block / objective group user created?
|
||||||
return (this.isContentBlock ? this.block.userCreated : !!this.block.owner)
|
return this.block.userCreated
|
||||||
// if so, is visibility not explicitly set for this school class?
|
// if so, is visibility not explicitly set for this school class?
|
||||||
? this.block.visibleFor.findIndex(el => el.id === this.schoolClass.id) === -1
|
? this.block.visibleFor.findIndex(el => el.id === this.schoolClass.id) === -1
|
||||||
// otherwise, is it explicitly hidden for this school class?
|
// otherwise, is it explicitly hidden for this school class?
|
||||||
|
|
@ -66,9 +66,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
// todo: refactor for single objectives when concept is clear
|
|
||||||
else {
|
|
||||||
mutation = UPDATE_OBJECTIVE_VISIBILITY_MUTATION;
|
mutation = UPDATE_OBJECTIVE_VISIBILITY_MUTATION;
|
||||||
variables = {
|
variables = {
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -106,6 +104,11 @@
|
||||||
.visibility-action {
|
.visibility-action {
|
||||||
margin-top: 9px;
|
margin-top: 9px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: -70px;
|
||||||
|
top: 0px;
|
||||||
|
display: grid;
|
||||||
|
|
||||||
&__visibility-menu {
|
&__visibility-menu {
|
||||||
top: 40px;
|
top: 40px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
fragment ObjectiveParts on ObjectiveNode {
|
fragment ObjectiveParts on ObjectiveNode {
|
||||||
id
|
id
|
||||||
text
|
text
|
||||||
|
userCreated
|
||||||
hiddenFor {
|
hiddenFor {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#import "../fragments/objectiveParts.gql"
|
||||||
|
mutation AddObjective($input: AddObjectiveInput!){
|
||||||
|
addObjective(input: $input) {
|
||||||
|
objective {
|
||||||
|
...ObjectiveParts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#{"input": {
|
||||||
|
# "objective": {
|
||||||
|
# "objectiveGroup": "asdas",
|
||||||
|
# "text": "Lern etwas"
|
||||||
|
# }}
|
||||||
|
#}
|
||||||
|
|
@ -43,7 +43,8 @@ export default new Vuex.Store({
|
||||||
scrollToAssignmentReady: state => state.scrollToAssignmentReady,
|
scrollToAssignmentReady: state => state.scrollToAssignmentReady,
|
||||||
scrollingToAssignment: state => state.scrollingToAssignment,
|
scrollingToAssignment: state => state.scrollingToAssignment,
|
||||||
currentProjectEntry: state => state.currentProjectEntry,
|
currentProjectEntry: state => state.currentProjectEntry,
|
||||||
editModule: state => state.editModule
|
editModule: state => state.editModule,
|
||||||
|
currentObjectiveGroup: state => state.currentObjectiveGroup
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
@ -61,6 +62,7 @@ export default new Vuex.Store({
|
||||||
commit('setContentBlockPosition', {});
|
commit('setContentBlockPosition', {});
|
||||||
commit('setParentRoom', null);
|
commit('setParentRoom', null);
|
||||||
commit('setParentModule', '');
|
commit('setParentModule', '');
|
||||||
|
// todo: remove
|
||||||
commit('setObjectiveGroupType', '');
|
commit('setObjectiveGroupType', '');
|
||||||
commit('setCurrentObjectiveGroup', '');
|
commit('setCurrentObjectiveGroup', '');
|
||||||
commit('setParentProject', null);
|
commit('setParentProject', null);
|
||||||
|
|
@ -86,6 +88,10 @@ export default new Vuex.Store({
|
||||||
commit('setContentBlockPosition', payload);
|
commit('setContentBlockPosition', payload);
|
||||||
dispatch('showModal', 'new-content-block-wizard');
|
dispatch('showModal', 'new-content-block-wizard');
|
||||||
},
|
},
|
||||||
|
addObjective({commit, dispatch}, payload) {
|
||||||
|
commit('setCurrentObjectiveGroup', payload);
|
||||||
|
dispatch('showModal', 'new-objective-wizard');
|
||||||
|
},
|
||||||
addRoomEntry({commit, dispatch}, payload) {
|
addRoomEntry({commit, dispatch}, payload) {
|
||||||
commit('setParentRoom', payload);
|
commit('setParentRoom', payload);
|
||||||
dispatch('showModal', 'new-room-entry-wizard');
|
dispatch('showModal', 'new-room-entry-wizard');
|
||||||
|
|
@ -94,6 +100,7 @@ export default new Vuex.Store({
|
||||||
commit('setCurrentRoomEntry', payload);
|
commit('setCurrentRoomEntry', payload);
|
||||||
dispatch('showModal', 'edit-room-entry-wizard');
|
dispatch('showModal', 'edit-room-entry-wizard');
|
||||||
},
|
},
|
||||||
|
// todo: remove
|
||||||
addObjectiveGroup({commit, dispatch}, {module, type}) {
|
addObjectiveGroup({commit, dispatch}, {module, type}) {
|
||||||
commit('setParentModule', module);
|
commit('setParentModule', module);
|
||||||
commit('setObjectiveGroupType', type);
|
commit('setObjectiveGroupType', type);
|
||||||
|
|
@ -179,6 +186,7 @@ export default new Vuex.Store({
|
||||||
setParentModule(state, payload) {
|
setParentModule(state, payload) {
|
||||||
state.parentModule = payload;
|
state.parentModule = payload;
|
||||||
},
|
},
|
||||||
|
// todo: remove
|
||||||
setObjectiveGroupType(state, payload) {
|
setObjectiveGroupType(state, payload) {
|
||||||
state.objectiveGroupType = payload;
|
state.objectiveGroupType = payload;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
.hideable-element {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&--hidden {
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -16,3 +16,4 @@
|
||||||
@import "actions";
|
@import "actions";
|
||||||
@import "navigation";
|
@import "navigation";
|
||||||
@import "survey";
|
@import "survey";
|
||||||
|
@import "visibility";
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@ class ObjectiveInput(InputObjectType):
|
||||||
id = graphene.ID()
|
id = graphene.ID()
|
||||||
|
|
||||||
|
|
||||||
|
class AddObjectiveArgument(InputObjectType):
|
||||||
|
text = graphene.String(required=True)
|
||||||
|
objective_group = graphene.ID(reuired=True)
|
||||||
|
|
||||||
class AddObjectiveGroupArgument(InputObjectType):
|
class AddObjectiveGroupArgument(InputObjectType):
|
||||||
title = graphene.String(required=True)
|
title = graphene.String(required=True)
|
||||||
module = graphene.ID(required=True)
|
module = graphene.ID(required=True)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class ObjectiveGroup(models.Model):
|
||||||
visible_for = models.ManyToManyField(SchoolClass, related_name='visible_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 '{} - {}'.format(self.module, self.title)
|
||||||
|
|
||||||
|
|
||||||
class Objective(models.Model):
|
class Objective(models.Model):
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from api.utils import get_object
|
||||||
from books.models import Module
|
from books.models import Module
|
||||||
from books.schema.inputs import UserGroupBlockVisibility
|
from books.schema.inputs import UserGroupBlockVisibility
|
||||||
from core.utils import set_visible_for, set_hidden_for
|
from core.utils import set_visible_for, set_hidden_for
|
||||||
from objectives.inputs import AddObjectiveGroupArgument, UpdateObjectiveGroupArgument
|
from objectives.inputs import AddObjectiveGroupArgument, UpdateObjectiveGroupArgument, AddObjectiveArgument
|
||||||
from objectives.models import ObjectiveProgressStatus, Objective, ObjectiveGroup
|
from objectives.models import ObjectiveProgressStatus, Objective, ObjectiveGroup
|
||||||
from objectives.schema import ObjectiveNode, ObjectiveGroupNode
|
from objectives.schema import ObjectiveNode, ObjectiveGroupNode
|
||||||
|
|
||||||
|
|
@ -60,6 +60,30 @@ class UpdateObjectiveVisibility(relay.ClientIDMutation):
|
||||||
return cls(objective=objective)
|
return cls(objective=objective)
|
||||||
|
|
||||||
|
|
||||||
|
class AddObjective(relay.ClientIDMutation):
|
||||||
|
class Input:
|
||||||
|
objective = graphene.Argument(AddObjectiveArgument)
|
||||||
|
|
||||||
|
objective = graphene.Field(ObjectiveNode)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
||||||
|
owner = info.context.user
|
||||||
|
if not owner.has_perm('users.can_manage_school_class_content'):
|
||||||
|
raise PermissionDenied('Missing permissions')
|
||||||
|
|
||||||
|
objective_data = kwargs.get('objective')
|
||||||
|
objective_group_id = objective_data.get('objective_group')
|
||||||
|
text = objective_data.get('text')
|
||||||
|
|
||||||
|
objective_group = get_object(ObjectiveGroup, objective_group_id)
|
||||||
|
|
||||||
|
objective = Objective.objects.create(text=text, owner=owner, group=objective_group)
|
||||||
|
|
||||||
|
return cls(objective=objective)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AddObjectiveGroup(relay.ClientIDMutation):
|
class AddObjectiveGroup(relay.ClientIDMutation):
|
||||||
class Input:
|
class Input:
|
||||||
objective_group = graphene.Argument(AddObjectiveGroupArgument)
|
objective_group = graphene.Argument(AddObjectiveGroupArgument)
|
||||||
|
|
@ -127,5 +151,6 @@ class UpdateObjectiveGroup(relay.ClientIDMutation):
|
||||||
class ObjectiveMutations:
|
class ObjectiveMutations:
|
||||||
update_objective_progress = UpdateObjectiveProgress.Field()
|
update_objective_progress = UpdateObjectiveProgress.Field()
|
||||||
update_objective_visibility = UpdateObjectiveVisibility.Field()
|
update_objective_visibility = UpdateObjectiveVisibility.Field()
|
||||||
|
add_objective = AddObjective.Field()
|
||||||
add_objective_group = AddObjectiveGroup.Field()
|
add_objective_group = AddObjectiveGroup.Field()
|
||||||
update_objective_group = UpdateObjectiveGroup.Field()
|
update_objective_group = UpdateObjectiveGroup.Field()
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ class ObjectiveGroupNode(DjangoObjectType):
|
||||||
|
|
||||||
class ObjectiveNode(DjangoObjectType):
|
class ObjectiveNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
|
user_created = graphene.Boolean()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Objective
|
model = Objective
|
||||||
|
|
@ -53,6 +54,9 @@ class ObjectiveNode(DjangoObjectType):
|
||||||
def resolve_objective_progress(self, info, **kwargs):
|
def resolve_objective_progress(self, info, **kwargs):
|
||||||
return self.objective_progress.filter(user=info.context.user)
|
return self.objective_progress.filter(user=info.context.user)
|
||||||
|
|
||||||
|
def resolve_user_created(self, info, **kwargs):
|
||||||
|
return self.owner is not None
|
||||||
|
|
||||||
|
|
||||||
class ObjectiveProgressStatusNode(DjangoObjectType):
|
class ObjectiveProgressStatusNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue