Add objectives to snapshot preview
This commit is contained in:
parent
293bdd84ce
commit
ef15a655b8
|
|
@ -53,8 +53,8 @@
|
||||||
props: {
|
props: {
|
||||||
module: {
|
module: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({}),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
BookmarkActions,
|
BookmarkActions,
|
||||||
|
|
@ -65,15 +65,15 @@
|
||||||
computed: {
|
computed: {
|
||||||
languageCommunicationObjectiveGroups() {
|
languageCommunicationObjectiveGroups() {
|
||||||
return this.module.objectiveGroups ? this.module.objectiveGroups
|
return this.module.objectiveGroups ? this.module.objectiveGroups
|
||||||
.filter(group => group.title === 'LANGUAGE_COMMUNICATION') : [];
|
.filter(group => group.title.toLowerCase() === 'language_communication') : [];
|
||||||
},
|
},
|
||||||
societyObjectiveGroups() {
|
societyObjectiveGroups() {
|
||||||
return this.module.objectiveGroups ? this.module.objectiveGroups
|
return this.module.objectiveGroups ? this.module.objectiveGroups
|
||||||
.filter(group => group.title === 'SOCIETY') : [];
|
.filter(group => group.title.toLowerCase() === 'society') : [];
|
||||||
},
|
},
|
||||||
interdisciplinaryObjectiveGroups() {
|
interdisciplinaryObjectiveGroups() {
|
||||||
return this.module.objectiveGroups ? this.module.objectiveGroups
|
return this.module.objectiveGroups ? this.module.objectiveGroups
|
||||||
.filter(group => group.title === 'INTERDISCIPLINARY') : [];
|
.filter(group => group.title.toLowerCase() === 'interdisciplinary') : [];
|
||||||
},
|
},
|
||||||
isStudent() {
|
isStudent() {
|
||||||
return !this.me.permissions.includes('users.can_manage_school_class_content');
|
return !this.me.permissions.includes('users.can_manage_school_class_content');
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
return hidden({
|
return hidden({
|
||||||
block: this.group,
|
block: this.group,
|
||||||
schoolClass: this.schoolClass,
|
schoolClass: this.schoolClass,
|
||||||
type: this.type
|
type: this.type,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/_variables.scss";
|
@import "~styles/helpers";
|
||||||
|
|
||||||
.objective-group {
|
.objective-group {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#import "../../fragments/contentBlockInterfaceParts.gql"
|
#import "../../fragments/contentBlockInterfaceParts.gql"
|
||||||
|
|
||||||
|
|
||||||
query SnapshotDetail($id: ID!) {
|
query SnapshotDetail($id: ID!) {
|
||||||
snapshot(id: $id) {
|
snapshot(id: $id) {
|
||||||
id
|
id
|
||||||
|
|
@ -15,6 +14,16 @@ query SnapshotDetail($id: ID!) {
|
||||||
hiddenObjectives
|
hiddenObjectives
|
||||||
}
|
}
|
||||||
creator
|
creator
|
||||||
|
objectiveGroups {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
displayTitle
|
||||||
|
objectives {
|
||||||
|
hidden
|
||||||
|
id
|
||||||
|
text
|
||||||
|
}
|
||||||
|
}
|
||||||
chapters {
|
chapters {
|
||||||
id
|
id
|
||||||
description
|
description
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,8 @@ class Snapshot(models.Model):
|
||||||
shared = models.BooleanField(default=False)
|
shared = models.BooleanField(default=False)
|
||||||
objective_groups = models.ManyToManyField(
|
objective_groups = models.ManyToManyField(
|
||||||
'objectives.ObjectiveGroup',
|
'objectives.ObjectiveGroup',
|
||||||
through=ObjectiveGroupSnapshot
|
through=ObjectiveGroupSnapshot,
|
||||||
|
related_name='+'
|
||||||
)
|
)
|
||||||
hidden_objectives = models.ManyToManyField(
|
hidden_objectives = models.ManyToManyField(
|
||||||
'objectives.Objective',
|
'objectives.Objective',
|
||||||
|
|
|
||||||
|
|
@ -44,15 +44,19 @@ class SnapshotChapter:
|
||||||
|
|
||||||
class SnapshotObjective:
|
class SnapshotObjective:
|
||||||
def __init__(self, objective, snapshot):
|
def __init__(self, objective, snapshot):
|
||||||
|
self.id = objective.id
|
||||||
self.text = objective.text
|
self.text = objective.text
|
||||||
self.hidden = snapshot.hidden_objectives.filter(id=objective.id).exists()
|
self.hidden = snapshot.hidden_objectives.filter(id=objective.id).exists()
|
||||||
|
|
||||||
|
|
||||||
class SnapshotObjectiveGroup:
|
class SnapshotObjectiveGroup:
|
||||||
def __init__(self, objective_group, snapshot):
|
def __init__(self, objective_group, hidden, snapshot):
|
||||||
self.title = objective_group.title
|
self.title = objective_group.title
|
||||||
|
self.display_title = objective_group.get_title_display()
|
||||||
|
self.hidden = hidden
|
||||||
|
self.id = objective_group.id
|
||||||
base_qs = objective_group.objectives
|
base_qs = objective_group.objectives
|
||||||
default = Q(owner__isnull=True)
|
default = Q(Q(owner__isnull=True) & Q(objectivesnapshot__snapshot__isnull=True))
|
||||||
this_snapshot = Q(objectivesnapshot__snapshot=snapshot)
|
this_snapshot = Q(objectivesnapshot__snapshot=snapshot)
|
||||||
self.objectives = [
|
self.objectives = [
|
||||||
SnapshotObjective(
|
SnapshotObjective(
|
||||||
|
|
@ -99,7 +103,9 @@ class SnapshotObjectiveGroupNode(ObjectType):
|
||||||
interfaces = (relay.Node,)
|
interfaces = (relay.Node,)
|
||||||
|
|
||||||
title = graphene.String(required=True)
|
title = graphene.String(required=True)
|
||||||
objectives = graphene.List(SnapshotObjectiveNode)
|
hidden = graphene.Boolean(required=True)
|
||||||
|
display_title = graphene.String(required=True)
|
||||||
|
objectives = graphene.List(SnapshotObjectiveNode, required=True)
|
||||||
|
|
||||||
|
|
||||||
class SnapshotNode(DjangoObjectType):
|
class SnapshotNode(DjangoObjectType):
|
||||||
|
|
@ -164,8 +170,9 @@ class SnapshotNode(DjangoObjectType):
|
||||||
def resolve_objective_groups(parent, info, **kwargs):
|
def resolve_objective_groups(parent, info, **kwargs):
|
||||||
return [
|
return [
|
||||||
SnapshotObjectiveGroup(
|
SnapshotObjectiveGroup(
|
||||||
objective_group=objective_group,
|
objective_group=objective_group_snapshot.objective_group,
|
||||||
|
hidden=objective_group_snapshot.hidden,
|
||||||
snapshot=parent
|
snapshot=parent
|
||||||
)
|
)
|
||||||
for objective_group in parent.objective_groups.all()
|
for objective_group_snapshot in parent.objective_groups.through.objects.filter(snapshot=parent)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from graphene.test import Client
|
||||||
from graphql_relay import to_global_id, from_global_id
|
from graphql_relay import to_global_id, from_global_id
|
||||||
|
|
||||||
from api.schema import schema
|
from api.schema import schema
|
||||||
|
from api.utils import get_object
|
||||||
from books.factories import ModuleFactory, ChapterFactory, ContentBlockFactory
|
from books.factories import ModuleFactory, ChapterFactory, ContentBlockFactory
|
||||||
from books.models import Snapshot, ChapterSnapshot
|
from books.models import Snapshot, ChapterSnapshot
|
||||||
from core.tests.base_test import SkillboxTestCase
|
from core.tests.base_test import SkillboxTestCase
|
||||||
|
|
@ -86,6 +87,16 @@ SNAPSHOT_MODULE_QUERY = """
|
||||||
query SnapshotDetail($id: ID!) {
|
query SnapshotDetail($id: ID!) {
|
||||||
snapshot(id: $id) {
|
snapshot(id: $id) {
|
||||||
id
|
id
|
||||||
|
objectiveGroups {
|
||||||
|
title
|
||||||
|
id
|
||||||
|
hidden
|
||||||
|
objectives {
|
||||||
|
hidden
|
||||||
|
id
|
||||||
|
text
|
||||||
|
}
|
||||||
|
}
|
||||||
chapters {
|
chapters {
|
||||||
id
|
id
|
||||||
description
|
description
|
||||||
|
|
@ -127,11 +138,11 @@ query SnapshotQuery($slug: String!) {
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def edges_to_array(entity):
|
|
||||||
return [edge['node'] for edge in entity.get('edges')]
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSnapshotTestCase(SkillboxTestCase):
|
class CreateSnapshotTestCase(SkillboxTestCase):
|
||||||
|
def _test_objective(self, objective, text, hidden):
|
||||||
|
self.assertEqual(objective['text'], text)
|
||||||
|
self.assertEqual(objective['hidden'], hidden)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.createDefault()
|
self.createDefault()
|
||||||
self.client = self.get_client()
|
self.client = self.get_client()
|
||||||
|
|
@ -168,12 +179,15 @@ class CreateSnapshotTestCase(SkillboxTestCase):
|
||||||
# snapshot S looks like module M for school class X
|
# snapshot S looks like module M for school class X
|
||||||
|
|
||||||
objective_group = ObjectiveGroupFactory(module=self.module)
|
objective_group = ObjectiveGroupFactory(module=self.module)
|
||||||
|
second_objective_group = ObjectiveGroupFactory(module=self.module)
|
||||||
|
|
||||||
self.visible_objective = ObjectiveFactory(text='visible-objective', group=objective_group)
|
self.visible_objective = ObjectiveFactory(text='visible-objective', group=objective_group)
|
||||||
self.hidden_objective = ObjectiveFactory(text='hidden-objective', group=objective_group)
|
self.hidden_objective = ObjectiveFactory(text='hidden-objective', group=objective_group)
|
||||||
self.custom_objective = ObjectiveFactory(text='custom-objective', group=objective_group, owner=self.teacher)
|
self.custom_objective = ObjectiveFactory(text='custom-objective', group=objective_group, owner=self.teacher)
|
||||||
|
|
||||||
self.hidden_objective.hidden_for.add(self.skillbox_class)
|
self.hidden_objective.hidden_for.add(self.skillbox_class)
|
||||||
self.custom_objective.visible_for.add(self.skillbox_class)
|
self.custom_objective.visible_for.add(self.skillbox_class)
|
||||||
|
second_objective_group.hidden_for.add(self.skillbox_class)
|
||||||
|
|
||||||
def _test_module_visibility(self, client, school_class_name):
|
def _test_module_visibility(self, client, school_class_name):
|
||||||
result = client.execute(MODULE_QUERY, variables={
|
result = client.execute(MODULE_QUERY, variables={
|
||||||
|
|
@ -254,12 +268,14 @@ class CreateSnapshotTestCase(SkillboxTestCase):
|
||||||
self.assertEqual(ChapterSnapshot.objects.count(), 2)
|
self.assertEqual(ChapterSnapshot.objects.count(), 2)
|
||||||
|
|
||||||
visible, hidden, custom = snapshot['objectiveGroups'][0]['objectives']
|
visible, hidden, custom = snapshot['objectiveGroups'][0]['objectives']
|
||||||
self.assertEqual(visible['text'], self.visible_objective.text)
|
|
||||||
self.assertEqual(visible['hidden'], False)
|
self._test_objective(objective=visible, text=self.visible_objective.text, hidden=False)
|
||||||
self.assertEqual(hidden['text'], self.hidden_objective.text)
|
self._test_objective(objective=hidden, text=self.hidden_objective.text, hidden=True)
|
||||||
self.assertEqual(hidden['hidden'], True)
|
self._test_objective(objective=custom, text=self.custom_objective.text, hidden=False)
|
||||||
self.assertEqual(custom['text'], self.custom_objective.text)
|
|
||||||
self.assertEqual(custom['hidden'], False)
|
id = snapshot['id']
|
||||||
|
snapshot = get_object(Snapshot, id)
|
||||||
|
self.assertEqual(snapshot.objective_groups.count(), 2)
|
||||||
|
|
||||||
|
|
||||||
def test_apply_snapshot(self):
|
def test_apply_snapshot(self):
|
||||||
|
|
@ -302,6 +318,18 @@ class CreateSnapshotTestCase(SkillboxTestCase):
|
||||||
self.assertEqual(second['hidden'], True)
|
self.assertEqual(second['hidden'], True)
|
||||||
self.assertEqual(third['title'], 'custom')
|
self.assertEqual(third['title'], 'custom')
|
||||||
|
|
||||||
|
objective_groups = snapshot['objectiveGroups']
|
||||||
|
self.assertEqual(len(objective_groups), 2)
|
||||||
|
objective_group1, objective_group2 = objective_groups
|
||||||
|
|
||||||
|
objective1, objective2, objective3 = objective_group1['objectives']
|
||||||
|
self._test_objective(objective1, self.visible_objective.text, False)
|
||||||
|
self._test_objective(objective2, self.hidden_objective.text, True)
|
||||||
|
self._test_objective(objective3, self.custom_objective.text, False)
|
||||||
|
|
||||||
|
self.assertEqual(objective_group2['hidden'], True)
|
||||||
|
|
||||||
|
|
||||||
def test_apply_initial_snapshot(self):
|
def test_apply_initial_snapshot(self):
|
||||||
teacher2 = User.objects.get(username='teacher2')
|
teacher2 = User.objects.get(username='teacher2')
|
||||||
teacher2_client = self.get_client(user=teacher2)
|
teacher2_client = self.get_client(user=teacher2)
|
||||||
|
|
|
||||||
|
|
@ -734,6 +734,7 @@ type ObjectiveNode implements Node {
|
||||||
hiddenFor: [SchoolClassNode]
|
hiddenFor: [SchoolClassNode]
|
||||||
visibleFor: [SchoolClassNode]
|
visibleFor: [SchoolClassNode]
|
||||||
order: Int
|
order: Int
|
||||||
|
hiddenForSnapshots(offset: Int, before: String, after: String, first: Int, last: Int): SnapshotNodeConnection!
|
||||||
pk: Int
|
pk: Int
|
||||||
userCreated: Boolean
|
userCreated: Boolean
|
||||||
mine: Boolean
|
mine: Boolean
|
||||||
|
|
@ -927,6 +928,8 @@ type SnapshotNode implements Node {
|
||||||
created: DateTime!
|
created: DateTime!
|
||||||
creator: String!
|
creator: String!
|
||||||
shared: Boolean!
|
shared: Boolean!
|
||||||
|
objectiveGroups: [SnapshotObjectiveGroupNode]
|
||||||
|
hiddenObjectives(offset: Int, before: String, after: String, first: Int, last: Int, text: String): ObjectiveNodeConnection!
|
||||||
title: String
|
title: String
|
||||||
metaTitle: String
|
metaTitle: String
|
||||||
heroImage: String
|
heroImage: String
|
||||||
|
|
@ -934,6 +937,30 @@ type SnapshotNode implements Node {
|
||||||
mine: Boolean
|
mine: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SnapshotNodeConnection {
|
||||||
|
pageInfo: PageInfo!
|
||||||
|
edges: [SnapshotNodeEdge]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapshotNodeEdge {
|
||||||
|
node: SnapshotNode
|
||||||
|
cursor: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapshotObjectiveGroupNode implements Node {
|
||||||
|
id: ID!
|
||||||
|
title: String!
|
||||||
|
hidden: Boolean!
|
||||||
|
displayTitle: String!
|
||||||
|
objectives: [SnapshotObjectiveNode]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type SnapshotObjectiveNode implements Node {
|
||||||
|
id: ID!
|
||||||
|
hidden: Boolean!
|
||||||
|
text: String!
|
||||||
|
}
|
||||||
|
|
||||||
input SpellCheckInput {
|
input SpellCheckInput {
|
||||||
text: String!
|
text: String!
|
||||||
assignment: ID!
|
assignment: ID!
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue