Add visibility popover to objective group widget

This commit is contained in:
Ramon Wenger 2018-10-31 15:37:46 +01:00
parent 53f50bdc13
commit 97bea4289e
9 changed files with 190 additions and 60 deletions

View File

@ -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);
} }

View File

@ -1,6 +1,11 @@
<template> <template>
<div class="objective-group"> <div class="objective-group">
<h4>{{group.displayTitle}}</h4> <div class="objective-group__actions">
<visibility-action :block="group">
</visibility-action>
</div>
<h4>{{group.displayTitle}} {{group.id}}</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>

View File

@ -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>

View File

@ -13,6 +13,7 @@
<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 MODULE_DETAILS_QUERY from '@/graphql/gql/moduleDetailsQuery.gql';
@ -20,7 +21,7 @@
// import store from '@/store/index'; // import store from '@/store/index';
export default { export default {
props: ['show', 'content-block'], props: ['show', 'block'],
components: { components: {
Checkbox Checkbox
@ -42,30 +43,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 +93,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 {

View File

@ -0,0 +1,24 @@
fragment ObjectiveGroupParts on ObjectiveGroupNode {
id
title
displayTitle
owner {
id
}
hiddenFor {
edges {
node {
id
name
}
}
}
visibleFor {
edges {
node {
id
name
}
}
}
}

View File

@ -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,9 +20,7 @@ query ModulesQuery($slug: String!) {
objectiveGroups { objectiveGroups {
edges { edges {
node { node {
id ...ObjectiveGroupParts
title
displayTitle
objectives { objectives {
edges { edges {
node { node {

View File

@ -0,0 +1,9 @@
#import "../fragments/objectiveGroupParts.gql"
mutation UpdateObjectiveGroupVisibility($input: UpdateObjectiveGroupVisibilityInput!) {
updateObjectiveGroupVisibility(input: $input) {
objectiveGroup {
...ObjectiveGroupParts
}
}
}

View File

@ -0,0 +1,5 @@
.action-icon {
width: 40px;
height: 40px;
fill: $color-grey;
}

View File

@ -12,3 +12,4 @@
@import "help-text"; @import "help-text";
@import "objective-group"; @import "objective-group";
@import "article"; @import "article";
@import "actions";