Rename block, update frontend
This commit is contained in:
parent
8e0f9fd377
commit
2fa006d790
|
|
@ -10,6 +10,7 @@
|
||||||
import DefaultLayout from '@/layouts/DefaultLayout';
|
import DefaultLayout from '@/layouts/DefaultLayout';
|
||||||
import SimpleLayout from '@/layouts/SimpleLayout';
|
import SimpleLayout from '@/layouts/SimpleLayout';
|
||||||
import BlankLayout from '@/layouts/BlankLayout';
|
import BlankLayout from '@/layouts/BlankLayout';
|
||||||
|
import FullScreenLayout from '@/layouts/FullScreenLayout';
|
||||||
import Modal from '@/components/Modal';
|
import Modal from '@/components/Modal';
|
||||||
import MobileNavigation from '@/components/MobileNavigation';
|
import MobileNavigation from '@/components/MobileNavigation';
|
||||||
import NewContentBlockWizard from '@/components/content-block-form/NewContentBlockWizard';
|
import NewContentBlockWizard from '@/components/content-block-form/NewContentBlockWizard';
|
||||||
|
|
@ -33,6 +34,7 @@
|
||||||
DefaultLayout,
|
DefaultLayout,
|
||||||
SimpleLayout,
|
SimpleLayout,
|
||||||
BlankLayout,
|
BlankLayout,
|
||||||
|
FullScreenLayout,
|
||||||
Modal,
|
Modal,
|
||||||
MobileNavigation,
|
MobileNavigation,
|
||||||
NewContentBlockWizard,
|
NewContentBlockWizard,
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
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 ModuleRoomSlug from '@/components/content-blocks/ModuleRoomSlug'
|
||||||
|
|
||||||
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';
|
||||||
|
|
@ -93,6 +94,7 @@
|
||||||
'genially_block': GeniallyBlock,
|
'genially_block': GeniallyBlock,
|
||||||
'subtitle': SubtitleBlock,
|
'subtitle': SubtitleBlock,
|
||||||
'content_list': ContentListBlock,
|
'content_list': ContentListBlock,
|
||||||
|
'module_room_slug': ModuleRoomSlug,
|
||||||
Survey,
|
Survey,
|
||||||
Solution,
|
Solution,
|
||||||
Assignment,
|
Assignment,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<template>
|
||||||
|
<div class="module-slug">
|
||||||
|
<router-link class="button button--primary" :to="{name: 'moduleRoom', params: { slug: value.slug }}">Raum anzeigen
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['value']
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "@/styles/_variables.scss";
|
||||||
|
|
||||||
|
.module-slug {
|
||||||
|
margin-bottom: $large-spacing;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import AddRoomEntryButton from '@/components/rooms/AddRoomEntryButton.vue';
|
||||||
|
import RoomEntry from '@/components/rooms/RoomEntry.vue';
|
||||||
|
import RoomGroupWidget from '@/components/rooms/RoomGroupWidget';
|
||||||
|
import EntryCountWidget from '@/components/rooms/EntryCountWidget';
|
||||||
|
import RoomActions from '@/components/rooms/RoomActions';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EntryCountWidget,
|
||||||
|
RoomGroupWidget,
|
||||||
|
AddRoomEntryButton,
|
||||||
|
RoomEntry,
|
||||||
|
RoomActions
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.$store.dispatch('setSpecialContainerClass', '');
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
room: [],
|
||||||
|
entries: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
roomEntryCount() {
|
||||||
|
return (this.room && this.room.roomEntries) ? this.room.roomEntries.length : 0
|
||||||
|
},
|
||||||
|
roomAppearance() {
|
||||||
|
return this.room ? this.room.appearance : ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,8 +25,10 @@
|
||||||
mounted () {
|
mounted () {
|
||||||
if (this.avatarUrl !== '') {
|
if (this.avatarUrl !== '') {
|
||||||
this.$refs.fakeImage.addEventListener('load', () => {
|
this.$refs.fakeImage.addEventListener('load', () => {
|
||||||
|
if (this.$refs.fakeImage) {
|
||||||
this.$refs.fakeImage.remove();
|
this.$refs.fakeImage.remove();
|
||||||
this.isAvatarLoaded = true;
|
this.isAvatarLoaded = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#import "./fragments/roomParts.gql"
|
||||||
|
#import "./fragments/roomEntryParts.gql"
|
||||||
|
query ModuleRoomEntriesQuery($slug: String, $classId: ID!) {
|
||||||
|
moduleRoom(slug: $slug, classId: $classId) {
|
||||||
|
...RoomParts
|
||||||
|
roomEntries {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...RoomEntryParts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,74 +35,6 @@
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@/styles/_variables.scss";
|
@import "@/styles/_variables.scss";
|
||||||
@import "@/styles/_mixins.scss";
|
@import "@/styles/_mixins.scss";
|
||||||
|
@import "@/styles/_default-layout.scss";
|
||||||
|
|
||||||
.skillbox {
|
|
||||||
margin: 0 auto;
|
|
||||||
width: 100%;
|
|
||||||
@supports (display: grid) {
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
grid-template-rows: auto 1fr;
|
|
||||||
min-height: 100vh;
|
|
||||||
grid-auto-rows: 1fr;
|
|
||||||
|
|
||||||
grid-template-areas: "h" "c";
|
|
||||||
padding-bottom: 50px;
|
|
||||||
|
|
||||||
&--show-filter {
|
|
||||||
grid-template-rows: auto auto 1fr;
|
|
||||||
-ms-grid-rows: 50px 50px 30px 1fr; // 1 extra row for gap
|
|
||||||
grid-template-areas: "h" "." "c";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For IE10+
|
|
||||||
*/
|
|
||||||
|
|
||||||
&--show-filter &__content {
|
|
||||||
-ms-grid-row: 4;
|
|
||||||
-ms-grid-column: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--show-filter &__filter-bar {
|
|
||||||
-ms-grid-row: 2;
|
|
||||||
-ms-grid-column: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For IE10+
|
|
||||||
*/
|
|
||||||
display: -ms-grid;
|
|
||||||
-ms-grid-rows: 50px 30px auto; // 1 extra row for gap
|
|
||||||
-ms-grid-columns: 1fr;
|
|
||||||
|
|
||||||
@include skillbox-colors;
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
grid-area: h;
|
|
||||||
-ms-grid-row: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__content {
|
|
||||||
-ms-grid-row: 3;
|
|
||||||
-ms-grid-column: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__footer {
|
|
||||||
grid-area: f;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For IE10+
|
|
||||||
*/
|
|
||||||
& > :nth-child(2) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
& > :nth-child(3) {
|
|
||||||
-ms-grid-row: 4;
|
|
||||||
-ms-grid-column: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
<template>
|
||||||
|
<div class="container skillbox" :class="specialContainerClass">
|
||||||
|
<div class="close-button" v-on:click="back">
|
||||||
|
<cross class="close-button__icon"></cross>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<router-view class="skillbox__content"></router-view>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Cross from '@/components/icons/Cross';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Cross
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
specialContainerClass() {
|
||||||
|
let cls = this.$store.state.specialContainerClass;
|
||||||
|
return [cls ? `skillbox--${cls}` : '']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
back() {
|
||||||
|
this.$router.go(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "@/styles/_default-layout.scss";
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
margin-top: $medium-spacing;
|
||||||
|
margin-right: $medium-spacing;
|
||||||
|
justify-self: end;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
display:flex;
|
||||||
|
justify-content:end;
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
<template>
|
||||||
|
<div class="room">
|
||||||
|
<div class="room__header">
|
||||||
|
<h1 class="room__title">{{room.title}}</h1>
|
||||||
|
<p class="room__intro">
|
||||||
|
{{room.description}}
|
||||||
|
</p>
|
||||||
|
<div class="room__meta">
|
||||||
|
<room-group-widget v-bind="room.schoolClass"></room-group-widget>
|
||||||
|
<entry-count-widget :entry-count="roomEntryCount"></entry-count-widget>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="room__content">
|
||||||
|
<add-room-entry-button :parent="room" v-if="room.id">
|
||||||
|
<!--
|
||||||
|
the v-if is there for the case where the room hasn't loaded yet, but there is already an attempt to create
|
||||||
|
a new room entry. mainly happens during cypress testing, but could also happen on a very slow connection
|
||||||
|
-->
|
||||||
|
</add-room-entry-button>
|
||||||
|
<room-entry v-for="entry in room.roomEntries" v-bind="entry" :key="entry.id"></room-entry>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MODULE_ROOM_ENTRIES_QUERY from '@/graphql/gql/moduleRoomEntryQuery.gql';
|
||||||
|
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||||
|
import roomMixin from '@/components/mixins/room'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['slug'],
|
||||||
|
mixins: [roomMixin],
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
room: [],
|
||||||
|
entries: [],
|
||||||
|
me: {
|
||||||
|
selectedClass: {
|
||||||
|
id: ''
|
||||||
|
},
|
||||||
|
permissions: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
apollo: {
|
||||||
|
moduleRoom: {
|
||||||
|
query: MODULE_ROOM_ENTRIES_QUERY,
|
||||||
|
variables() {
|
||||||
|
return {
|
||||||
|
slug: this.slug,
|
||||||
|
classId: this.me.selectedClass.id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// manual: true,
|
||||||
|
// todo: do we really need manual here? update should do the trick too
|
||||||
|
result({data, loading, networkStatus}) {
|
||||||
|
if (!loading) {
|
||||||
|
this.room = Object.assign({}, this.$getRidOfEdges(data).moduleRoom);
|
||||||
|
this.$store.dispatch('setSpecialContainerClass', this.room.appearance);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pollInterval: 5000,
|
||||||
|
},
|
||||||
|
me: {
|
||||||
|
query: ME_QUERY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "@/styles/_room.scss";
|
||||||
|
</style>
|
||||||
|
|
@ -25,46 +25,11 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ROOM_ENTRIES_QUERY from '@/graphql/gql/roomEntriesQuery.gql';
|
import ROOM_ENTRIES_QUERY from '@/graphql/gql/roomEntriesQuery.gql';
|
||||||
|
import roomMixin from '@/components/mixins/room'
|
||||||
import AddRoomEntryButton from '@/components/rooms/AddRoomEntryButton.vue';
|
|
||||||
import RoomEntry from '@/components/rooms/RoomEntry.vue';
|
|
||||||
import RoomGroupWidget from '@/components/rooms/RoomGroupWidget';
|
|
||||||
import EntryCountWidget from '@/components/rooms/EntryCountWidget';
|
|
||||||
import RoomActions from '@/components/rooms/RoomActions';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['slug'],
|
props: ['slug'],
|
||||||
|
mixins: [roomMixin],
|
||||||
components: {
|
|
||||||
EntryCountWidget,
|
|
||||||
RoomGroupWidget,
|
|
||||||
AddRoomEntryButton,
|
|
||||||
RoomEntry,
|
|
||||||
RoomActions
|
|
||||||
},
|
|
||||||
|
|
||||||
beforeDestroy() {
|
|
||||||
this.$store.dispatch('setSpecialContainerClass', '');
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
room: [],
|
|
||||||
entries: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
roomEntryCount() {
|
|
||||||
return (this.room && this.room.roomEntries) ? this.room.roomEntries.length : 0
|
|
||||||
},
|
|
||||||
roomAppearance() {
|
|
||||||
return this.room ? this.room.appearance : ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
apollo: {
|
apollo: {
|
||||||
modules: {
|
modules: {
|
||||||
|
|
@ -89,54 +54,5 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/_variables.scss";
|
@import "@/styles/_room.scss";
|
||||||
@import "@/styles/_functions.scss";
|
|
||||||
@import "@/styles/_mixins.scss";
|
|
||||||
|
|
||||||
.room {
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: auto 1fr;
|
|
||||||
margin-bottom: -50px;
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
padding: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__intro {
|
|
||||||
font-family: $sans-serif-font-family;
|
|
||||||
font-weight: $font-weight-regular;
|
|
||||||
font-size: toRem(17px);
|
|
||||||
max-width: 900px;
|
|
||||||
line-height: 1.5;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__meta {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
@include desktop {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
}
|
|
||||||
justify-content: start;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
& > :first-child {
|
|
||||||
margin-left: $large-spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > :nth-child(2) {
|
|
||||||
margin-left: $large-spacing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__content {
|
|
||||||
padding: 50px 15px;
|
|
||||||
background-color: rgba($color-charcoal-dark, 0.18);
|
|
||||||
@include desktop {
|
|
||||||
columns: 4;
|
|
||||||
padding: 50px 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import editProject from '@/pages/editProject'
|
||||||
import newProject from '@/pages/newProject'
|
import newProject from '@/pages/newProject'
|
||||||
import surveyPage from '@/pages/survey'
|
import surveyPage from '@/pages/survey'
|
||||||
import styleGuidePage from '@/pages/styleguide'
|
import styleGuidePage from '@/pages/styleguide'
|
||||||
|
import moduleRoom from '@/pages/moduleRoom'
|
||||||
|
|
||||||
import store from '@/store/index';
|
import store from '@/store/index';
|
||||||
|
|
||||||
|
|
@ -46,13 +47,20 @@ const routes = [
|
||||||
name: 'submissions',
|
name: 'submissions',
|
||||||
component: submissions,
|
component: submissions,
|
||||||
meta: {filter: true}
|
meta: {filter: true}
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{path: '/rooms', name: 'rooms', component: rooms, meta: {filter: true}},
|
{path: '/rooms', name: 'rooms', component: rooms, meta: {filter: true}},
|
||||||
{path: '/new-room/', name: 'new-room', component: newRoom},
|
{path: '/new-room/', name: 'new-room', component: newRoom},
|
||||||
{path: '/edit-room/:id', name: 'edit-room', component: editRoom, props: true},
|
{path: '/edit-room/:id', name: 'edit-room', component: editRoom, props: true},
|
||||||
{path: '/room/:slug', name: 'room', component: room, props: true},
|
{path: '/room/:slug', name: 'room', component: room, props: true},
|
||||||
|
{
|
||||||
|
path: '/module-room/:slug',
|
||||||
|
name: 'moduleRoom',
|
||||||
|
component: moduleRoom,
|
||||||
|
props: true,
|
||||||
|
meta: {layout: 'fullScreen'}
|
||||||
|
},
|
||||||
{path: '/article/:slug', name: 'article', component: article, meta: {layout: 'simple'}},
|
{path: '/article/:slug', name: 'article', component: article, meta: {layout: 'simple'}},
|
||||||
{
|
{
|
||||||
path: '/instruments/:slug',
|
path: '/instruments/:slug',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
@import "@/styles/_variables.scss";
|
||||||
|
@import "@/styles/_mixins.scss";
|
||||||
|
|
||||||
|
.skillbox {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
@supports (display: grid) {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
min-height: 100vh;
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
|
||||||
|
grid-template-areas: "h" "c";
|
||||||
|
padding-bottom: 50px;
|
||||||
|
|
||||||
|
&--show-filter {
|
||||||
|
grid-template-rows: auto auto 1fr;
|
||||||
|
-ms-grid-rows: 50px 50px 30px 1fr; // 1 extra row for gap
|
||||||
|
grid-template-areas: "h" "." "c";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For IE10+
|
||||||
|
*/
|
||||||
|
|
||||||
|
&--show-filter &__content {
|
||||||
|
-ms-grid-row: 4;
|
||||||
|
-ms-grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--show-filter &__filter-bar {
|
||||||
|
-ms-grid-row: 2;
|
||||||
|
-ms-grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For IE10+
|
||||||
|
*/
|
||||||
|
display: -ms-grid;
|
||||||
|
-ms-grid-rows: 50px 30px auto; // 1 extra row for gap
|
||||||
|
-ms-grid-columns: 1fr;
|
||||||
|
|
||||||
|
@include skillbox-colors;
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
grid-area: h;
|
||||||
|
-ms-grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
-ms-grid-row: 3;
|
||||||
|
-ms-grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer {
|
||||||
|
grid-area: f;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For IE10+
|
||||||
|
*/
|
||||||
|
& > :nth-child(2) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :nth-child(3) {
|
||||||
|
-ms-grid-row: 4;
|
||||||
|
-ms-grid-column: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
@import "@/styles/_variables.scss";
|
||||||
|
@import "@/styles/_functions.scss";
|
||||||
|
@import "@/styles/_mixins.scss";
|
||||||
|
|
||||||
|
.room {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
margin-bottom: -50px;
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__intro {
|
||||||
|
font-family: $sans-serif-font-family;
|
||||||
|
font-weight: $font-weight-regular;
|
||||||
|
font-size: toRem(17px);
|
||||||
|
max-width: 900px;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__meta {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
@include desktop {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
justify-content: start;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
& > :first-child {
|
||||||
|
margin-left: $large-spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :nth-child(2) {
|
||||||
|
margin-left: $large-spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
padding: 50px 15px;
|
||||||
|
background-color: rgba($color-charcoal-dark, 0.18);
|
||||||
|
@include desktop {
|
||||||
|
columns: 4;
|
||||||
|
padding: 50px 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
@import "reset";
|
@import "reset";
|
||||||
@import "typography";
|
@import "typography";
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
@import "default-layout";
|
||||||
@import "buttons";
|
@import "buttons";
|
||||||
@import "forms";
|
@import "forms";
|
||||||
@import "uploadcare_overwrite";
|
@import "uploadcare_overwrite";
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@ from portfolio.schema import PortfolioQuery
|
||||||
from surveys.schema import SurveysQuery
|
from surveys.schema import SurveysQuery
|
||||||
from surveys.mutations import SurveysMutations
|
from surveys.mutations import SurveysMutations
|
||||||
from rooms.mutations import RoomMutations
|
from rooms.mutations import RoomMutations
|
||||||
from rooms.schema import RoomsQuery, AdminRoomsQuery
|
from rooms.schema import RoomsQuery, ModuleRoomsQuery
|
||||||
from users.schema import UsersQuery
|
from users.schema import UsersQuery
|
||||||
from users.mutations import ProfileMutations
|
from users.mutations import ProfileMutations
|
||||||
|
|
||||||
|
|
||||||
class Query(UsersQuery, AdminRoomsQuery, RoomsQuery, ObjectivesQuery, BookQuery, AssignmentsQuery, StudentSubmissionQuery,
|
class Query(UsersQuery, ModuleRoomsQuery, RoomsQuery, ObjectivesQuery, BookQuery, AssignmentsQuery, StudentSubmissionQuery,
|
||||||
BasicKnowledgeQuery, PortfolioQuery, MyActivityQuery, SurveysQuery, graphene.ObjectType):
|
BasicKnowledgeQuery, PortfolioQuery, MyActivityQuery, SurveysQuery, graphene.ObjectType):
|
||||||
node = relay.Node.Field()
|
node = relay.Node.Field()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ class InstrumentTextBlock(blocks.StructBlock):
|
||||||
text = blocks.RichTextBlock(features=INSTRUMENTS_RICH_TEXT_FEATURES)
|
text = blocks.RichTextBlock(features=INSTRUMENTS_RICH_TEXT_FEATURES)
|
||||||
|
|
||||||
|
|
||||||
class AdminRoomSlugBlock(blocks.StructBlock):
|
class ModuleRoomSlugBlock(blocks.StructBlock):
|
||||||
class Meta:
|
class Meta:
|
||||||
icon = 'link'
|
icon = 'link'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.0.6 on 2019-08-07 13:40
|
# Generated by Django 2.0.6 on 2019-08-08 06:49
|
||||||
|
|
||||||
import assignments.models
|
import assignments.models
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
@ -19,6 +19,6 @@ class Migration(migrations.Migration):
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='contentblock',
|
model_name='contentblock',
|
||||||
name='contents',
|
name='contents',
|
||||||
field=wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(required=True, target_model=['basicknowledge.BasicKnowledge']))])), ('assignment', wagtail.core.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.core.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('solution', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))], icon='tick')), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('infogram_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock()), ('title', wagtail.core.blocks.TextBlock())])), ('genially_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('admin_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())])), ('content_list_item', wagtail.core.blocks.StreamBlock([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(required=True, target_model=['basicknowledge.BasicKnowledge']))])), ('assignment', wagtail.core.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.core.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('solution', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))], icon='tick')), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('infogram_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock()), ('title', wagtail.core.blocks.TextBlock())])), ('genially_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('admin_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())]))]))], blank=True, null=True),
|
field=wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(required=True, target_model=['basicknowledge.BasicKnowledge']))])), ('assignment', wagtail.core.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.core.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('solution', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))], icon='tick')), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('infogram_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock()), ('title', wagtail.core.blocks.TextBlock())])), ('genially_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('module_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())])), ('content_list_item', wagtail.core.blocks.StreamBlock([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(required=True, target_model=['basicknowledge.BasicKnowledge']))])), ('assignment', wagtail.core.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.core.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('solution', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))], icon='tick')), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('infogram_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock()), ('title', wagtail.core.blocks.TextBlock())])), ('genially_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('module_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())]))]))], blank=True, null=True),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
@ -7,7 +7,7 @@ from wagtail.core.fields import StreamField
|
||||||
from wagtail.images.blocks import ImageChooserBlock
|
from wagtail.images.blocks import ImageChooserBlock
|
||||||
|
|
||||||
from books.blocks import TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, DocumentBlock, \
|
from books.blocks import TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, DocumentBlock, \
|
||||||
ImageUrlBlock, AssignmentBlock, InfogramBlock, GeniallyBlock, SubtitleBlock, SurveyBlock, AdminRoomSlugBlock
|
ImageUrlBlock, AssignmentBlock, InfogramBlock, GeniallyBlock, SubtitleBlock, SurveyBlock, ModuleRoomSlugBlock
|
||||||
from core.wagtail_utils import StrictHierarchyPage
|
from core.wagtail_utils import StrictHierarchyPage
|
||||||
from users.models import SchoolClass
|
from users.models import SchoolClass
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ class ContentBlock(StrictHierarchyPage):
|
||||||
('infogram_block', InfogramBlock()),
|
('infogram_block', InfogramBlock()),
|
||||||
('genially_block', GeniallyBlock()),
|
('genially_block', GeniallyBlock()),
|
||||||
('subtitle', SubtitleBlock()),
|
('subtitle', SubtitleBlock()),
|
||||||
('admin_room_slug', AdminRoomSlugBlock())
|
('module_room_slug', ModuleRoomSlugBlock())
|
||||||
]
|
]
|
||||||
|
|
||||||
content_list_item = StreamBlock(content_blocks)
|
content_list_item = StreamBlock(content_blocks)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from graphene_django.filter import DjangoFilterConnectionField
|
||||||
|
|
||||||
from api.utils import get_object
|
from api.utils import get_object
|
||||||
from books.utils import are_solutions_enabled_for
|
from books.utils import are_solutions_enabled_for
|
||||||
|
from rooms.models import ModuleRoomSlug
|
||||||
from ..models import Book, Topic, Module, Chapter, ContentBlock
|
from ..models import Book, Topic, Module, Chapter, ContentBlock
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -25,9 +26,23 @@ class ContentBlockNode(DjangoObjectType):
|
||||||
return self.owner is not None and self.owner.pk == info.context.user.pk
|
return self.owner is not None and self.owner.pk == info.context.user.pk
|
||||||
|
|
||||||
def resolve_contents(self, info, **kwargs):
|
def resolve_contents(self, info, **kwargs):
|
||||||
if not are_solutions_enabled_for(info.context.user, self.module):
|
updated_stream_data = []
|
||||||
self.contents.stream_data = [content for content in self.contents.stream_data if
|
for content in self.contents.stream_data:
|
||||||
content['type'] != 'solution']
|
if not are_solutions_enabled_for(info.context.user, self.module) and content['type'] == 'solution':
|
||||||
|
continue
|
||||||
|
|
||||||
|
if content['type'] == 'module_room_slug':
|
||||||
|
try:
|
||||||
|
module_room_slug = ModuleRoomSlug.objects.get(title=content['value']['title'])
|
||||||
|
content['value'] = {
|
||||||
|
'title': content['value']['title'],
|
||||||
|
'slug': module_room_slug.slug
|
||||||
|
}
|
||||||
|
except ModuleRoomSlug.DoesNotExist:
|
||||||
|
pass
|
||||||
|
updated_stream_data.append(content)
|
||||||
|
|
||||||
|
self.contents.stream_data = updated_stream_data
|
||||||
return self.contents
|
return self.contents
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from rooms.models import Room, RoomEntry, AdminGeneratedRoomSlug
|
from rooms.models import Room, RoomEntry, ModuleRoomSlug
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Room)
|
@admin.register(Room)
|
||||||
|
|
@ -15,7 +15,7 @@ class RoomEntryAdmin(admin.ModelAdmin):
|
||||||
list_filter = ('room', 'author')
|
list_filter = ('room', 'author')
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AdminGeneratedRoomSlug)
|
@admin.register(ModuleRoomSlug)
|
||||||
class AdminGeneratedRoomSlugAdmin(admin.ModelAdmin):
|
class AdminGeneratedRoomSlugAdmin(admin.ModelAdmin):
|
||||||
list_display = ('id', 'slug', 'title')
|
list_display = ('id', 'slug', 'title')
|
||||||
list_filter = ('slug', 'title')
|
list_filter = ('slug', 'title')
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from wagtail.core.rich_text import RichText
|
||||||
|
|
||||||
from books.factories import TextBlockFactory, ImageUrlBlockFactory, LinkBlockFactory
|
from books.factories import TextBlockFactory, ImageUrlBlockFactory, LinkBlockFactory
|
||||||
from core.factories import fake, fake_paragraph
|
from core.factories import fake, fake_paragraph
|
||||||
from rooms.models import Room, RoomEntry, AdminGeneratedRoomSlug
|
from rooms.models import Room, RoomEntry, ModuleRoomSlug
|
||||||
from users.models import SchoolClass
|
from users.models import SchoolClass
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -79,9 +79,9 @@ class RoomEntryFactory(factory.django.DjangoModelFactory):
|
||||||
return cls._generate(CREATE_STRATEGY, kwargs)
|
return cls._generate(CREATE_STRATEGY, kwargs)
|
||||||
|
|
||||||
|
|
||||||
class AdminGeneratedRoomSlugFactory(factory.django.DjangoModelFactory):
|
class ModuleRoomSlugFactory(factory.django.DjangoModelFactory):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AdminGeneratedRoomSlug
|
model = ModuleRoomSlug
|
||||||
|
|
||||||
slug = factory.Sequence(lambda n: u'slug-{:d}'.format(n))
|
slug = factory.Sequence(lambda n: u'slug-{:d}'.format(n))
|
||||||
title = factory.Sequence(lambda n: u'Title {:d}'.format(n))
|
title = factory.Sequence(lambda n: u'Title {:d}'.format(n))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.0.6 on 2019-08-07 13:23
|
# Generated by Django 2.0.6 on 2019-08-08 06:49
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django_extensions.db.fields
|
import django_extensions.db.fields
|
||||||
|
|
@ -12,7 +12,7 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='AdminGeneratedRoomSlug',
|
name='ModuleRoomSlug',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('title', models.CharField(max_length=255, verbose_name='title')),
|
('title', models.CharField(max_length=255, verbose_name='title')),
|
||||||
|
|
@ -44,7 +44,7 @@ class RoomEntry(TitleSlugDescriptionModel):
|
||||||
return user.is_superuser or self.room.school_class.is_user_in_schoolclass(user)
|
return user.is_superuser or self.room.school_class.is_user_in_schoolclass(user)
|
||||||
|
|
||||||
|
|
||||||
class AdminGeneratedRoomSlug(TitleSlugDescriptionModel):
|
class ModuleRoomSlug(TitleSlugDescriptionModel):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'AdmimSlug {}-{}'.format(self.id, self.title)
|
return 'ModuleRoomSlug {}-{}'.format(self.id, self.title)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from graphene_django import DjangoObjectType
|
||||||
from graphene_django.filter import DjangoFilterConnectionField
|
from graphene_django.filter import DjangoFilterConnectionField
|
||||||
|
|
||||||
from api.utils import get_object, get_by_id_or_slug
|
from api.utils import get_object, get_by_id_or_slug
|
||||||
from rooms.models import Room, RoomEntry, AdminGeneratedRoomSlug
|
from rooms.models import Room, RoomEntry, ModuleRoomSlug
|
||||||
from users.models import SchoolClass
|
from users.models import SchoolClass
|
||||||
from users.schema import UserNode
|
from users.schema import UserNode
|
||||||
|
|
||||||
|
|
@ -85,25 +85,27 @@ class RoomsQuery(object):
|
||||||
return RoomEntry.objects.all()
|
return RoomEntry.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class AdminRoomsQuery(object):
|
class ModuleRoomsQuery(object):
|
||||||
|
|
||||||
admin_room = graphene.Field(RoomNode, slug=graphene.String(), class_id=graphene.ID())
|
module_room = graphene.Field(RoomNode, slug=graphene.String(), class_id=graphene.ID())
|
||||||
|
|
||||||
def resolve_admin_room(self, info, **kwargs):
|
def resolve_module_room(self, info, **kwargs):
|
||||||
|
|
||||||
slug = kwargs.get('slug')
|
|
||||||
schoolclass = get_object(SchoolClass, kwargs.get('class_id'))
|
schoolclass = get_object(SchoolClass, kwargs.get('class_id'))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
slug = AdminGeneratedRoomSlug.objects.get(slug=slug)
|
slug = ModuleRoomSlug.objects.get(slug=kwargs.get('slug'))
|
||||||
except AdminGeneratedRoomSlug.DoesNotExist:
|
except ModuleRoomSlug.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if schoolclass is None or not schoolclass.is_user_in_schoolclass(info.context.user):
|
if schoolclass is None or not schoolclass.is_user_in_schoolclass(info.context.user):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
room, created = Room.objects.get_or_create(school_class=schoolclass, user_created=False, slug=slug,
|
room, created = Room.objects.get_or_create(school_class=schoolclass, user_created=False, slug=slug.slug,
|
||||||
title=slug.title, appearance='blue')
|
title=slug.title, appearance='blue')
|
||||||
|
if created:
|
||||||
|
room.slug = slug.slug
|
||||||
|
room.save()
|
||||||
|
|
||||||
if not room.user_created and room.school_class.is_user_in_schoolclass(info.context.user):
|
if not room.user_created and room.school_class.is_user_in_schoolclass(info.context.user):
|
||||||
return room
|
return room
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from graphql_relay import to_global_id
|
||||||
|
|
||||||
from api.schema import schema
|
from api.schema import schema
|
||||||
from core.factories import UserFactory
|
from core.factories import UserFactory
|
||||||
from rooms.factories import RoomFactory, AdminGeneratedRoomSlugFactory
|
from rooms.factories import RoomFactory, ModuleRoomSlugFactory
|
||||||
from users.factories import SchoolClassFactory
|
from users.factories import SchoolClassFactory
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ class AdminRoomQueryPermission(TestCase):
|
||||||
self.room1 = RoomFactory(school_class=self.sc1)
|
self.room1 = RoomFactory(school_class=self.sc1)
|
||||||
self.room2 = RoomFactory(school_class=sc2)
|
self.room2 = RoomFactory(school_class=sc2)
|
||||||
|
|
||||||
self.admin_slug = AdminGeneratedRoomSlugFactory(title='some title')
|
self.module_room_slug = ModuleRoomSlugFactory(title='some title')
|
||||||
|
|
||||||
self.sc1_id = to_global_id('SchoolClass', self.sc1.pk)
|
self.sc1_id = to_global_id('SchoolClass', self.sc1.pk)
|
||||||
self.sc2_id = to_global_id('SchoolClass', sc2.pk)
|
self.sc2_id = to_global_id('SchoolClass', sc2.pk)
|
||||||
|
|
@ -37,8 +37,8 @@ class AdminRoomQueryPermission(TestCase):
|
||||||
self.client = Client(schema=schema, context_value=request)
|
self.client = Client(schema=schema, context_value=request)
|
||||||
|
|
||||||
self.query = '''
|
self.query = '''
|
||||||
query AdminRoomQuery($slug: String, $classId: ID!) {
|
query ModuleRoomEntriesQuery($slug: String, $classId: ID!) {
|
||||||
adminRoom(slug: $slug, classId: $classId) {
|
moduleRoom(slug: $slug, classId: $classId) {
|
||||||
title
|
title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ class AdminRoomQueryPermission(TestCase):
|
||||||
'classId': 'norealId'
|
'classId': 'norealId'
|
||||||
})
|
})
|
||||||
self.assertIsNone(result.get('errors'))
|
self.assertIsNone(result.get('errors'))
|
||||||
self.assertIsNone(result.get('data').get('adminRoom'))
|
self.assertIsNone(result.get('data').get('moduleRoom'))
|
||||||
|
|
||||||
def test_should_return_none_if_class_id_does_not_exist(self):
|
def test_should_return_none_if_class_id_does_not_exist(self):
|
||||||
|
|
||||||
|
|
@ -60,32 +60,32 @@ class AdminRoomQueryPermission(TestCase):
|
||||||
'classId': 'norealId'
|
'classId': 'norealId'
|
||||||
})
|
})
|
||||||
self.assertIsNone(result.get('errors'))
|
self.assertIsNone(result.get('errors'))
|
||||||
self.assertIsNone(result.get('data').get('adminRoom'))
|
self.assertIsNone(result.get('data').get('moduleRoom'))
|
||||||
|
|
||||||
def test_user_should_not_be_able_to_create_room_for_other_class(self):
|
def test_user_should_not_be_able_to_create_room_for_other_class(self):
|
||||||
|
|
||||||
result = self.client.execute(self.query, variables={
|
result = self.client.execute(self.query, variables={
|
||||||
'slug': self.admin_slug.slug,
|
'slug': self.module_room_slug.slug,
|
||||||
'classId': self.sc2_id
|
'classId': self.sc2_id
|
||||||
})
|
})
|
||||||
|
|
||||||
self.assertIsNone(result.get('errors'))
|
self.assertIsNone(result.get('errors'))
|
||||||
self.assertIsNone(result.get('data').get('adminRoom'))
|
self.assertIsNone(result.get('data').get('moduleRoom'))
|
||||||
|
|
||||||
def test_should_create_room_if_none_exists(self):
|
def test_should_create_room_if_none_exists(self):
|
||||||
|
|
||||||
result = self.client.execute(self.query, variables={
|
result = self.client.execute(self.query, variables={
|
||||||
'slug': self.admin_slug.slug,
|
'slug': self.module_room_slug.slug,
|
||||||
'classId': self.sc1_id
|
'classId': self.sc1_id
|
||||||
})
|
})
|
||||||
|
|
||||||
self.assertIsNone(result.get('errors'))
|
self.assertIsNone(result.get('errors'))
|
||||||
self.assertEqual(result.get('data').get('adminRoom').get('title'), self.admin_slug.title)
|
self.assertEqual(result.get('data').get('moduleRoom').get('title'), self.module_room_slug.title)
|
||||||
|
|
||||||
def test_should_return_room_if_one_exists(self):
|
def test_should_return_room_if_one_exists(self):
|
||||||
|
|
||||||
existing_room = RoomFactory(school_class=self.sc1, user_created=False)
|
existing_room = RoomFactory(school_class=self.sc1, user_created=False)
|
||||||
admin_slug = AdminGeneratedRoomSlugFactory(slug=existing_room.slug, title=existing_room.title)
|
admin_slug = ModuleRoomSlugFactory(slug=existing_room.slug, title=existing_room.title)
|
||||||
|
|
||||||
result = self.client.execute(self.query, variables={
|
result = self.client.execute(self.query, variables={
|
||||||
'slug': admin_slug.slug,
|
'slug': admin_slug.slug,
|
||||||
|
|
@ -93,4 +93,4 @@ class AdminRoomQueryPermission(TestCase):
|
||||||
})
|
})
|
||||||
|
|
||||||
self.assertIsNone(result.get('errors'))
|
self.assertIsNone(result.get('errors'))
|
||||||
self.assertEqual(result.get('data').get('adminRoom').get('title'), existing_room.title)
|
self.assertEqual(result.get('data').get('moduleRoom').get('title'), existing_room.title)
|
||||||
|
|
@ -63,7 +63,7 @@ class RoomQueryPermission(TestCase):
|
||||||
|
|
||||||
def test_student_should_only_user_created_rooms(self):
|
def test_student_should_only_user_created_rooms(self):
|
||||||
|
|
||||||
admin_room = RoomFactory(school_class=self.room1.school_class, user_created=False)
|
modlue_room = RoomFactory(school_class=self.room1.school_class, user_created=False)
|
||||||
|
|
||||||
query = '''
|
query = '''
|
||||||
query {
|
query {
|
||||||
|
|
@ -80,7 +80,7 @@ class RoomQueryPermission(TestCase):
|
||||||
result = self.client.execute(query)
|
result = self.client.execute(query)
|
||||||
self.assertIsNone(result.get('errors'))
|
self.assertIsNone(result.get('errors'))
|
||||||
self.assertEqual(len(result.get('data').get('rooms').get('edges')), 1)
|
self.assertEqual(len(result.get('data').get('rooms').get('edges')), 1)
|
||||||
self.assertNotEqual(result.get('data').get('rooms').get('edges')[0].get('node').get('title'), admin_room.title)
|
self.assertNotEqual(result.get('data').get('rooms').get('edges')[0].get('node').get('title'), modlue_room.title)
|
||||||
|
|
||||||
|
|
||||||
class RoomEntryQueryPermissions(TestCase):
|
class RoomEntryQueryPermissions(TestCase):
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
# @author: chrigu <christian.cueni@iterativ.ch>
|
# @author: chrigu <christian.cueni@iterativ.ch>
|
||||||
from wagtail.core import hooks
|
from wagtail.core import hooks
|
||||||
|
|
||||||
from rooms.models import AdminGeneratedRoomSlug
|
from rooms.models import ModuleRoomSlug
|
||||||
|
|
||||||
|
|
||||||
@hooks.register('after_edit_page')
|
@hooks.register('after_edit_page')
|
||||||
|
|
@ -21,13 +21,13 @@ def do_after_page_edit(request, page):
|
||||||
title = block[1]['title']
|
title = block[1]['title']
|
||||||
if isinstance(block, dict):
|
if isinstance(block, dict):
|
||||||
title = block['value']['title']
|
title = block['value']['title']
|
||||||
AdminGeneratedRoomSlug.objects.get_or_create(title=title)
|
ModuleRoomSlug.objects.get_or_create(title=title)
|
||||||
|
|
||||||
|
|
||||||
def get_room_blocks(page):
|
def get_room_blocks(page):
|
||||||
top_level_admin_slug_blocks = get_block_from_stream_data(page.contents.stream_data, 'admin_room_slug')
|
top_level_module_room_slug_blocks = get_block_from_stream_data(page.contents.stream_data, 'module_room_slug')
|
||||||
content_list_admin_slug_blocks = get_admin_slugs_from_content_list(page.contents.stream_data)
|
content_list_module_room_slug_blocks = get_admin_slugs_from_content_list(page.contents.stream_data)
|
||||||
return top_level_admin_slug_blocks + content_list_admin_slug_blocks
|
return top_level_module_room_slug_blocks + content_list_module_room_slug_blocks
|
||||||
|
|
||||||
|
|
||||||
def get_block_from_stream_data(stream_data, block_name):
|
def get_block_from_stream_data(stream_data, block_name):
|
||||||
|
|
@ -39,9 +39,9 @@ def get_block_from_stream_data(stream_data, block_name):
|
||||||
|
|
||||||
|
|
||||||
def get_admin_slugs_from_content_list(stream_data):
|
def get_admin_slugs_from_content_list(stream_data):
|
||||||
admin_slug_blocks = []
|
module_room_slug_blocks = []
|
||||||
content_list_items = get_block_from_stream_data(stream_data, 'content_list_item')
|
content_list_items = get_block_from_stream_data(stream_data, 'content_list_item')
|
||||||
for content_list_item in content_list_items:
|
for content_list_item in content_list_items:
|
||||||
admin_slug_blocks = admin_slug_blocks + get_block_from_stream_data(content_list_item[1].stream_data,
|
module_room_slug_blocks = module_room_slug_blocks + get_block_from_stream_data(content_list_item[1].stream_data,
|
||||||
'admin_room_slug')
|
'module_room_slug')
|
||||||
return admin_slug_blocks
|
return module_room_slug_blocks
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue