Clean up and simplify some code

This commit is contained in:
Ramon Wenger 2022-01-27 15:07:59 +01:00
parent 71ed5931c7
commit 37af5c0412
26 changed files with 109 additions and 133 deletions

View File

@ -24,19 +24,11 @@
"slug": "geld-und-kauf", "slug": "geld-und-kauf",
"__typename": "TopicNode" "__typename": "TopicNode"
}, },
"schoolClasses": { "schoolClasses": [{
"edges": [
{
"node": {
"id": "U2Nob29sQ2xhc3NOb2RlOjE=", "id": "U2Nob29sQ2xhc3NOb2RlOjE=",
"name": "FLID2018a", "name": "FLID2018a",
"__typename": "SchoolClassNode" "__typename": "SchoolClassNode"
}, }],
"__typename": "SchoolClassNodeEdge"
}
],
"__typename": "SchoolClassNodeConnection"
},
"__typename": "UserNode", "__typename": "UserNode",
"onboardingVisited": true, "onboardingVisited": true,
"permissions": [] "permissions": []

View File

@ -62,11 +62,7 @@ export default {
readOnly: false, readOnly: false,
onboardingVisited: true, onboardingVisited: true,
selectedClass, selectedClass,
schoolClasses: { schoolClasses: [selectedClass],
edges: [
{node: selectedClass},
],
},
recentModules: { recentModules: {
edges: [], edges: [],
}, },

View File

@ -15,9 +15,7 @@ describe('Apply module visibility', () => {
const {me: minimalMe} = getMinimalMe({}); const {me: minimalMe} = getMinimalMe({});
const me = { const me = {
...minimalMe, ...minimalMe,
schoolClasses: { schoolClasses
edges: schoolClasses.map(scn => ({node: scn}))
}
}; };
// name: '[\'FLID2018a\', \'Andere Klasse\']' // name: '[\'FLID2018a\', \'Andere Klasse\']'
const operations = { const operations = {

View File

@ -28,7 +28,7 @@ describe('New student', () => {
return { return {
...me, ...me,
onboardingVisited, onboardingVisited,
schoolClasses: {edges: schoolClasses}, schoolClasses,
selectedClass: getSelectedClass(), selectedClass: getSelectedClass(),
}; };
}; };

View File

@ -8,6 +8,7 @@ const getOperations = ({readOnly, classReadOnly = false}) => ({
...minimalModule, ...minimalModule,
}, },
}, },
UpdateLastModule: {}
}); });
const moduleNavigationTest = ({readOnly, classReadOnly = false, displayMenu}) => { const moduleNavigationTest = ({readOnly, classReadOnly = false, displayMenu}) => {

View File

@ -243,23 +243,18 @@ describe('The Room Page', () => {
cy.getByDataCy('add-room-entry-modal').should('exist'); cy.getByDataCy('add-room-entry-modal').should('exist');
}); });
it('changes class while on room page', () => { it.only('changes class while on room page', () => {
const {me} = MeQuery; const {me} = MeQuery;
const otherClass = {
id: btoa('SchoolClassNode:34'),
name: 'Other Class',
readOnly: false
};
const operations = { const operations = {
MeQuery: { MeQuery: {
me: { me: {
...me, ...me,
schoolClasses: { schoolClasses: [...me.schoolClasses, otherClass],
edges: [
...me.schoolClasses.edges,
{
node: {
id: btoa('SchoolClassNode:other-class'),
name: 'Other Class'
},
},
],
},
}, },
}, },
RoomEntriesQuery, RoomEntriesQuery,
@ -267,6 +262,15 @@ describe('The Room Page', () => {
updateSettings: { updateSettings: {
success: true success: true
} }
},
ModuleDetailsQuery: {
me: {
selectedClass: otherClass
}
},
MySchoolClassQuery: {},
RoomsQuery: {
rooms: []
} }
}; };
@ -277,5 +281,6 @@ describe('The Room Page', () => {
cy.getByDataCy('room-title').should('contain', 'A Room'); cy.getByDataCy('room-title').should('contain', 'A Room');
cy.selectClass('Other Class'); cy.selectClass('Other Class');
cy.url().should('include', 'rooms'); cy.url().should('include', 'rooms');
cy.getByDataCy('selected-class-name').should('contain', 'Other Class');
}); });
}); });

View File

@ -254,17 +254,13 @@ describe('Teacher Class Management', () => {
let selectedClass = teacher.selectedClass; let selectedClass = teacher.selectedClass;
const schoolClasses = [ const schoolClasses = [
{ teacher.selectedClass
node: teacher.selectedClass
}
]; ];
const me = () => ({ const me = () => ({
...teacher, ...teacher,
selectedClass, selectedClass,
schoolClasses: { schoolClasses
edges: schoolClasses
}
}); });
cy.mockGraphqlOps({ cy.mockGraphqlOps({
@ -278,9 +274,7 @@ describe('Teacher Class Management', () => {
name, name,
readOnly: false readOnly: false
}; };
schoolClasses.push({ schoolClasses.push(schoolClass);
node: schoolClass
});
selectedClass = schoolClass; selectedClass = schoolClass;
return { return {
createSchoolClass: { createSchoolClass: {

View File

@ -11,12 +11,7 @@ describe('Sidebar', () => {
MeQuery: { MeQuery: {
me: { me: {
...me, ...me,
schoolClasses: { schoolClasses: [...me.schoolClasses, {}],
edges: [
...me.schoolClasses.edges,
{node: {}},
],
},
}, },
}, },
ProjectsQuery: { ProjectsQuery: {

View File

@ -3,7 +3,7 @@
export const getMinimalMe = ({readOnly = false, classReadOnly = false, isTeacher = true} = {}) => { export const getMinimalMe = ({readOnly = false, classReadOnly = false, isTeacher = true} = {}) => {
const selectedClass = { const selectedClass = {
name: 'Selected Class', name: 'Selected Class',
id: btoa('SchoolClassNode:selectedClassId'), id: btoa('SchoolClassNode:987'),
readOnly: classReadOnly, readOnly: classReadOnly,
}; };
return { return {
@ -12,11 +12,7 @@ export const getMinimalMe = ({readOnly = false, classReadOnly = false, isTeacher
readOnly, readOnly,
isTeacher, isTeacher,
selectedClass, selectedClass,
schoolClasses: { schoolClasses: [selectedClass],
edges: [
{node: selectedClass},
],
},
}, },
}; };
}; };
@ -69,13 +65,7 @@ export const getMe = ({schoolClasses, teacher}) => {
'slug': 'geld-und-kauf', 'slug': 'geld-und-kauf',
'__typename': 'TopicNode', '__typename': 'TopicNode',
}, },
'schoolClasses': { 'schoolClasses': schoolClassNodes,
'edges': schoolClassNodes.map(scn => ({
node: scn,
'__typename': 'SchoolClassNodeEdge',
})),
'__typename': 'SchoolClassNodeConnection',
},
'__typename': 'UserNode', '__typename': 'UserNode',
'onboardingVisited': true, 'onboardingVisited': true,
'permissions': teacher ? ['users.can_manage_school_class_content'] : [], 'permissions': teacher ? ['users.can_manage_school_class_content'] : [],

View File

@ -99,7 +99,7 @@
if (this.currentFilter.id === '') { if (this.currentFilter.id === '') {
return true; return true;
} }
return submission.student.schoolClasses.edges.some(edge => edge.node.id === this.currentFilter.id); return submission.student.schoolClasses.some(schoolClass => schoolClass .id === this.currentFilter.id);
} }
}, },

View File

@ -61,11 +61,13 @@
if (success) { if (success) {
const {rooms} = store.readQuery({query: ROOMS_QUERY}); const {rooms} = store.readQuery({query: ROOMS_QUERY});
if (rooms) { if (rooms) {
const index = rooms.findIndex(edge => edge.node.id === this.id); const index = rooms.findIndex(room => room.id === this.id);
console.log(`found room index ${index} - rooms length ${rooms.length}`);
const slicedRooms = [ const slicedRooms = [
rooms.slice(0, index), ...rooms.slice(0, index),
rooms.slice(index+1) ...rooms.slice(index+1)
]; ];
console.log(`slicedRooms length ${slicedRooms.length}`);
const data = { const data = {
rooms: slicedRooms rooms: slicedRooms
}; };

View File

@ -30,10 +30,6 @@ fragment UserParts on PrivateUserNode {
} }
} }
schoolClasses { schoolClasses {
edges {
node {
...SchoolClassParts ...SchoolClassParts
} }
} }
}
}

View File

@ -12,13 +12,9 @@ query AssignmentWithSubmissions($id: ID!) {
firstName firstName
lastName lastName
schoolClasses { schoolClasses {
edges {
node {
...SchoolClassParts ...SchoolClassParts
} }
} }
}
}
submissionFeedback { submissionFeedback {
id id
text text

View File

@ -3,8 +3,6 @@ query RoomEntryQuery($slug: String!) {
roomEntry(slug: $slug) { roomEntry(slug: $slug) {
...RoomEntryParts ...RoomEntryParts
comments { comments {
edges {
node {
text text
owner { owner {
firstName firstName
@ -15,5 +13,3 @@ query RoomEntryQuery($slug: String!) {
} }
} }
} }
}
}

View File

@ -84,7 +84,7 @@ function redirectUsersWithoutValidLicense() {
function redirectStudentsWithoutClass() { function redirectStudentsWithoutClass() {
return privateApolloClient.query({ return privateApolloClient.query({
query: ME_QUERY, query: ME_QUERY,
}).then(({data}) => data.me.schoolClasses.edges.length === 0 && !data.me.isTeacher); }).then(({data}) => data.me.schoolClasses.length === 0 && !data.me.isTeacher);
} }
function redirectUsersToOnboarding() { function redirectUsersToOnboarding() {

View File

@ -8,12 +8,9 @@ export default {
this.$log.debug('updating school class', schoolClass); this.$log.debug('updating school class', schoolClass);
const {me} = store.readQuery({query}); const {me} = store.readQuery({query});
if (me) { if (me) {
let edges = [ let schoolClasses = [
...me.schoolClasses.edges, ...me.schoolClasses,
{ schoolClass
node: schoolClass,
__typename: 'SchoolClassNodeEdge'
}
]; ];
// me.schoolClasses.edges // me.schoolClasses.edges
const selectedClass = { const selectedClass = {
@ -24,10 +21,7 @@ export default {
const data = { const data = {
me: { me: {
...me, ...me,
schoolClasses: { schoolClasses,
...me.schoolClasses,
edges
},
selectedClass selectedClass
} }
}; };

View File

@ -51,6 +51,7 @@ export default {
me: { me: {
query: ME_QUERY, query: ME_QUERY,
update(data) { update(data) {
// todo: refactor
return this.$getRidOfEdges(data).me; return this.$getRidOfEdges(data).me;
}, },
fetchPolicy: 'cache-first' fetchPolicy: 'cache-first'

View File

@ -12,16 +12,21 @@ export default {
shared, shared,
}, },
}, },
update(store, {data: {updateProjectSharedState: {shared, errors}}}) { update(store, {data: {updateProjectSharedState: {shared: final, errors}}}) {
if (!errors) { if (!errors) {
const query = PROJECT_QUERY; const query = PROJECT_QUERY;
const variables = { const variables = {
id: id, id: id,
}; };
const data = store.readQuery({query, variables}); const {project} = store.readQuery({query, variables});
if (data) { if (project) {
data.project.final = shared; const data = {
project: {
...project,
final
}
};
store.writeQuery({query, variables, data}); store.writeQuery({query, variables, data});
} }
} }

View File

@ -16,11 +16,21 @@ export default {
} }
}, },
update(store) { update(store) {
let meData = store.readQuery({query: ME_QUERY}); let {me} = store.readQuery({query: ME_QUERY});
meData.me.selectedClass = selectedClass; console.log(`storing in cache: ${selectedClass.name}`);
const data = {
me: {
...me,
selectedClass: {
readOnly: false, // assume this, it will be reloaded later anyway
...selectedClass
}
}
};
console.log(`writing data`, data);
store.writeQuery({query: ME_QUERY, data: meData}); store.writeQuery({query: ME_QUERY, data});
innerApollo.mutate({ innerApollo.mutate({
mutation: DELETE_MODULE_NODES mutation: DELETE_MODULE_NODES

View File

@ -68,7 +68,8 @@
computed: { computed: {
comments() { comments() {
return (this.roomEntry && this.roomEntry.comments) ? this.roomEntry.comments.edges.map(edge => edge.node) : []; console.log(this.roomEntry);
return (this.roomEntry && this.roomEntry.comments) ? this.roomEntry.comments : [];
}, },
}, },
@ -88,15 +89,21 @@
const variables = { const variables = {
slug: this.roomEntry.slug, slug: this.roomEntry.slug,
}; };
const data = store.readQuery({ const {roomEntry} = store.readQuery({
query, query,
variables, variables,
}); });
if (data) { if (roomEntry) {
data.roomEntry.comments.edges.unshift({ const comments = [
node: comment, comment,
__typename: 'CommentNodeEdge' ...roomEntry.comments
}); ];
const data = {
roomEntry: {
...roomEntry,
comments
}
};
store.writeQuery({query, variables, data}); store.writeQuery({query, variables, data});
} }
} }

View File

@ -159,10 +159,15 @@
update: (store, {data: {updateAnswer: {answer}}}) => { update: (store, {data: {updateAnswer: {answer}}}) => {
const query = SURVEY_QUERY; const query = SURVEY_QUERY;
const variables = {id: this.id}; const variables = {id: this.id};
const queryData = store.readQuery({query, variables}); const {survey} = store.readQuery({query, variables});
if (queryData.survey) { if (survey) {
queryData.survey.answer = answer; const newData = { // data is already in use in parent scope
store.writeQuery({query, variables, data: queryData}); survey: {
...survey,
answer
}
};
store.writeQuery({query, variables, data: newData});
} }
}, },
}).then(() => { }).then(() => {

View File

@ -1,4 +1,6 @@
const getRidOfEdges = (collection) => { const getRidOfEdges = (collection) => {
// todo: get rid of this, this probably doesn't work too well with immutable objects
// todo: don't use edges if they're not necessary
if (typeof collection === 'object' && collection && !Array.isArray(collection)) { if (typeof collection === 'object' && collection && !Array.isArray(collection)) {
let newObj = {}; let newObj = {};
for (const k in collection) { for (const k in collection) {

View File

@ -26,7 +26,7 @@ class CommentNode(DjangoObjectType):
class RoomEntryNode(DjangoObjectType): class RoomEntryNode(DjangoObjectType):
pk = graphene.Int() pk = graphene.Int()
author = graphene.Field('users.schema.PublicUserNode') author = graphene.Field('users.schema.PublicUserNode')
comments = DjangoFilterConnectionField(CommentNode) comments = graphene.List(CommentNode)
class Meta: class Meta:
model = RoomEntry model = RoomEntry
@ -36,6 +36,10 @@ class RoomEntryNode(DjangoObjectType):
def resolve_pk(self, *args, **kwargs): def resolve_pk(self, *args, **kwargs):
return self.id return self.id
@staticmethod
def resolve_comments(parent: RoomEntry, *args, **kwargs):
return parent.comments.all()
class RoomNode(DjangoObjectType): class RoomNode(DjangoObjectType):
pk = graphene.Int() pk = graphene.Int()

View File

@ -47,14 +47,10 @@ mutation AddComment($input: AddCommentInput!) {
query CommentsQuery($id: ID!) { query CommentsQuery($id: ID!) {
roomEntry(id: $id) { roomEntry(id: $id) {
comments { comments {
edges {
node {
text text
} }
} }
} }
}
}
""" """
result = self.get_client().execute(query, variables={"id": self.room_entry_id}) result = self.get_client().execute(query, variables={"id": self.room_entry_id})
self.assertIsNone(result.get('errors')) self.assertIsNone(result.get('errors'))

View File

@ -266,16 +266,6 @@ type CommentNode implements Node {
id: ID! id: ID!
} }
type CommentNodeConnection {
pageInfo: PageInfo!
edges: [CommentNodeEdge]!
}
type CommentNodeEdge {
node: CommentNode
cursor: String!
}
type ContentBlockBookmarkNode implements Node { type ContentBlockBookmarkNode implements Node {
id: ID! id: ID!
user: PrivateUserNode! user: PrivateUserNode!
@ -842,7 +832,7 @@ type PrivateUserNode implements Node {
email: String! email: String!
onboardingVisited: Boolean! onboardingVisited: Boolean!
team: TeamNode team: TeamNode
schoolClasses(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection! schoolClasses: [SchoolClassNode]
id: ID! id: ID!
pk: Int pk: Int
permissions: [String] permissions: [String]
@ -905,7 +895,7 @@ type RoomEntryNode implements Node {
room: RoomNode! room: RoomNode!
author: PublicUserNode author: PublicUserNode
contents: GenericStreamFieldType contents: GenericStreamFieldType
comments(offset: Int, before: String, after: String, first: Int, last: Int, owner: ID): CommentNodeConnection comments: [CommentNode]
pk: Int pk: Int
} }

View File

@ -105,6 +105,7 @@ class PrivateUserNode(DjangoObjectType):
expiry_date = graphene.String() expiry_date = graphene.String()
is_teacher = graphene.Boolean() is_teacher = graphene.Boolean()
old_classes = DjangoFilterConnectionField(SchoolClassNode) old_classes = DjangoFilterConnectionField(SchoolClassNode)
school_classes =graphene.List(SchoolClassNode)
recent_modules = DjangoFilterConnectionField(ModuleNode, filterset_class=RecentModuleFilter) recent_modules = DjangoFilterConnectionField(ModuleNode, filterset_class=RecentModuleFilter)
team = graphene.Field(TeamNode) team = graphene.Field(TeamNode)
read_only = graphene.Boolean() read_only = graphene.Boolean()