diff --git a/client/src/App.vue b/client/src/App.vue index f678448e..0d87bfc2 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -13,6 +13,7 @@ import NewContentBlockWizard from '@/components/content-block-form/NewContentBlockWizard'; import EditContentBlockWizard from '@/components/content-block-form/EditContentBlockWizard'; import NewRoomEntryWizard from '@/components/rooms/room-entries/NewRoomEntryWizard'; + import EditRoomEntryWizard from '@/components/rooms/room-entries/EditRoomEntryWizard'; export default { name: 'App', @@ -24,7 +25,8 @@ Modal, NewContentBlockWizard, EditContentBlockWizard, - NewRoomEntryWizard + NewRoomEntryWizard, + EditRoomEntryWizard }, computed: { diff --git a/client/src/components/rooms/RoomEntry.vue b/client/src/components/rooms/RoomEntry.vue index 8ae844fd..a7e3ebe1 100644 --- a/client/src/components/rooms/RoomEntry.vue +++ b/client/src/components/rooms/RoomEntry.vue @@ -6,6 +6,7 @@ + + + + diff --git a/client/src/graphql/gql/mutations/updateRoomEntry.gql b/client/src/graphql/gql/mutations/updateRoomEntry.gql new file mode 100644 index 00000000..9ffb75d6 --- /dev/null +++ b/client/src/graphql/gql/mutations/updateRoomEntry.gql @@ -0,0 +1,9 @@ +#import "../fragments/roomEntryParts.gql" +mutation UpdateRoomEntry($input: UpdateRoomEntryInput!){ + updateRoomEntry(input: $input) { + roomEntry { + ...RoomEntryParts + } + errors + } +} diff --git a/client/src/graphql/gql/roomEntryByIdQuery.gql b/client/src/graphql/gql/roomEntryByIdQuery.gql new file mode 100644 index 00000000..3d9a42e6 --- /dev/null +++ b/client/src/graphql/gql/roomEntryByIdQuery.gql @@ -0,0 +1,6 @@ +#import "./fragments/roomEntryParts.gql" +query RoomEntryQuery($id: ID!) { + roomEntry(id: $id) { + ...RoomEntryParts + } +} diff --git a/client/src/store/index.js b/client/src/store/index.js index be7ae52c..50899556 100644 --- a/client/src/store/index.js +++ b/client/src/store/index.js @@ -13,6 +13,7 @@ export default new Vuex.Store({ scrollPosition: 0, filterForSchoolClass: '', currentContentBlock: '', + currentRoomEntry: '', parentRoom: null }, @@ -44,6 +45,10 @@ export default new Vuex.Store({ commit('setParentRoom', payload); dispatch('showModal', 'new-room-entry-wizard'); }, + editRoomEntry({commit, dispatch}, payload) { + commit('setCurrentRoomEntry', payload); + dispatch('showModal', 'edit-room-entry-wizard'); + }, showModal({commit}, payload) { document.body.classList.add('no-scroll'); // won't get at the body any other way commit('setModal', payload); @@ -77,6 +82,9 @@ export default new Vuex.Store({ }, setParentRoom(state, payload) { state.parentRoom = payload; + }, + setCurrentRoomEntry(state, payload) { + state.currentRoomEntry = payload; } } }) diff --git a/server/rooms/inputs.py b/server/rooms/inputs.py index 0f4bd10c..b8c78018 100644 --- a/server/rooms/inputs.py +++ b/server/rooms/inputs.py @@ -20,8 +20,15 @@ class UpdateRoomArgument(RoomInput): id = graphene.ID(required=True) -class AddRoomEntryArgument(InputObjectType): +class RoomEntryArgument(InputObjectType): title = graphene.String(required=True) subtitle = graphene.String() contents = graphene.List(ContentElementInput) + + +class AddRoomEntryArgument(RoomEntryArgument): room = graphene.ID(required=True) + + +class UpdateRoomEntryArgument(RoomEntryArgument): + id = graphene.ID(required=True) diff --git a/server/rooms/mutations.py b/server/rooms/mutations.py index 22082b79..bc43bebc 100644 --- a/server/rooms/mutations.py +++ b/server/rooms/mutations.py @@ -1,9 +1,9 @@ import graphene from graphene import relay -from graphql_relay import to_global_id +from graphql_relay import to_global_id, from_global_id from api.utils import get_object -from rooms.inputs import UpdateRoomArgument, AddRoomArgument, AddRoomEntryArgument +from rooms.inputs import UpdateRoomArgument, AddRoomArgument, AddRoomEntryArgument, UpdateRoomEntryArgument from rooms.models import Room, RoomEntry from rooms.schema import RoomNode, RoomEntryNode from rooms.serializers import RoomSerializer, RoomEntrySerializer @@ -71,20 +71,22 @@ class DeleteRoom(relay.ClientIDMutation): return cls(success=True) -class AddRoomEntry(relay.ClientIDMutation): - class Input: - room_entry = graphene.Argument(AddRoomEntryArgument) - +class MutateRoomEntry(relay.ClientIDMutation): room_entry = graphene.Field(RoomEntryNode) errors = graphene.List(graphene.String) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): room_entry_data = kwargs.get('room_entry') - room_entry_data['room'] = get_object(Room, room_entry_data.get('room')).id + if room_entry_data.get('room') is not None: + room_entry_data['room'] = get_object(Room, room_entry_data.get('room')).id room_entry_data['author'] = info.context.user.pk - serializer = RoomEntrySerializer(data=room_entry_data) + if room_entry_data.get('id') is not None: + instance = get_object(RoomEntry, room_entry_data.get('id')) + serializer = RoomEntrySerializer(instance, data=room_entry_data, partial=True) + else: + serializer = RoomEntrySerializer(data=room_entry_data) if serializer.is_valid(): serializer.save() @@ -94,6 +96,16 @@ class AddRoomEntry(relay.ClientIDMutation): return cls(room_entry=None, errors=['{}: {}'.format(key, value) for key, value in serializer.errors.items()]) +class AddRoomEntry(MutateRoomEntry): + class Input: + room_entry = graphene.Argument(AddRoomEntryArgument) + + +class UpdateRoomEntry(MutateRoomEntry): + class Input: + room_entry = graphene.Argument(UpdateRoomEntryArgument) + + class DeleteRoomEntry(relay.ClientIDMutation): class Input: id = graphene.ID(required=True) @@ -121,3 +133,4 @@ class RoomMutations: delete_room = DeleteRoom.Field() add_room_entry = AddRoomEntry.Field() delete_room_entry = DeleteRoomEntry.Field() + update_room_entry = UpdateRoomEntry.Field()