Add new edit page for room entries

Also use slug instead of id to identify room entries
This commit is contained in:
Ramon Wenger 2022-06-27 11:29:01 +02:00
parent cb84a1576c
commit a81bb0e1e8
10 changed files with 140 additions and 111 deletions

View File

@ -34,8 +34,8 @@
<room-entry-actions <room-entry-actions
data-cy="room-entry-actions" data-cy="room-entry-actions"
class="room-entry__more" class="room-entry__more"
:slug="slug"
v-if="myEntry" v-if="myEntry"
:id="id"
/> />
</div> </div>
</template> </template>

View File

@ -3,13 +3,13 @@
<popover-link <popover-link
icon="trash-icon" icon="trash-icon"
text="Eintrag löschen" text="Eintrag löschen"
@link-action="deleteRoomEntry(id)" @link-action="deleteRoomEntry(slug)"
/> />
<popover-link <popover-link
icon="pen-icon" icon="pen-icon"
data-cy="edit-room-entry" data-cy="edit-room-entry"
text="Eintrag bearbeiten" text="Eintrag bearbeiten"
@link-action="editRoomEntry(id)" @link-action="editRoomEntry(slug)"
/> />
</more-actions> </more-actions>
</template> </template>
@ -19,10 +19,11 @@
import MoreActions from '@/components/rooms/MoreActions'; import MoreActions from '@/components/rooms/MoreActions';
import DELETE_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/deleteRoomEntry'; import DELETE_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/deleteRoomEntry';
import ROOM_ENTRIES_QUERY from 'gql/queries/roomEntriesQuery'; import ROOM_ENTRIES_QUERY from 'gql/queries/roomEntriesQuery';
import {UPDATE_ROOM_ENTRY_PAGE} from '@/router/room.names';
export default { export default {
props: { props: {
id: { slug: {
type: String, type: String,
default: '', default: '',
}, },
@ -40,12 +41,12 @@
}, },
methods: { methods: {
deleteRoomEntry(id) { deleteRoomEntry(slug) {
this.$apollo.mutate({ this.$apollo.mutate({
mutation: DELETE_ROOM_ENTRY_MUTATION, mutation: DELETE_ROOM_ENTRY_MUTATION,
variables: { variables: {
input: { input: {
id, slug,
}, },
}, },
update(store, {data: {deleteRoomEntry: {success, roomSlug}}}) { update(store, {data: {deleteRoomEntry: {success, roomSlug}}}) {
@ -54,15 +55,22 @@
const variables = {slug: roomSlug}; const variables = {slug: roomSlug};
const data = store.readQuery({query, variables}); const data = store.readQuery({query, variables});
if (data) { if (data) {
data.room.roomEntries.edges.splice(data.room.roomEntries.edges.findIndex(edge => edge.node.id === id), 1); // todo: make immutable
data.room.roomEntries.edges.splice(data.room.roomEntries.edges.findIndex(edge => edge.node.slug === slug), 1);
store.writeQuery({query, data, variables}); store.writeQuery({query, data, variables});
} }
} }
}, },
}); });
}, },
editRoomEntry(id) { editRoomEntry(slug) {
this.$store.dispatch('editRoomEntry', id); this.$router.push({
name: UPDATE_ROOM_ENTRY_PAGE,
params: {
slug: this.$route.params.slug,
entrySlug: slug
}
});
}, },
}, },
}; };

View File

@ -1,92 +0,0 @@
<template>
<contents-form
:content-block="entry"
:show-task-selection="false"
:disable-save="saving"
data-cy="add-room-entry-modal"
block-type="RoomEntry"
@save="saveEntry"
@hide="hideModal"
/>
</template>
<script>
// todo: delete this
import NEW_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/addRoomEntry.gql';
import ROOM_ENTRIES_QUERY from '@/graphql/gql/queries/roomEntriesQuery.gql';
import ContentsForm from '@/components/content-block-form/ContentsForm';
export default {
components: {
ContentsForm
},
data() {
return {
entry: {
title: '',
contents: []
},
saving: false
};
},
computed: {
room() {
return this.$store.state.parentRoom;
}
},
methods: {
saveEntry(entry) {
this.saving = true;
this.$apollo.mutate({
mutation: NEW_ROOM_ENTRY_MUTATION,
variables: {
input: {
roomEntry: Object.assign({}, entry, {
room: this.room.id
})
}
},
update: (store, {data: {addRoomEntry: {roomEntry}}}) => {
try {
const query = ROOM_ENTRIES_QUERY;
const variables = {slug: this.room.slug};
const {room} = store.readQuery({query, variables});
if (room && room.roomEntries) {
const newEdge ={
node: roomEntry,
__typename: 'RoomEntryNodeEdge'
};
const edges = [
newEdge,
...room.roomEntries.edges
];
const data = {
room: {
...room,
roomEntries: {
...room.roomEntries,
edges
}
}
};
store.writeQuery({query, variables, data});
}
} catch (e) {
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
}
}
}).then(() => {
this.saving = false;
this.hideModal();
});
},
hideModal() {
this.$store.dispatch('hideModal');
},
}
};
</script>

View File

@ -0,0 +1,110 @@
<template>
<content-block-form
:content-block="roomEntry"
:features="features"
v-if="roomEntry.id"
@save="save"
@back="goBack"
/>
</template>
<script>
import Vue from 'vue';
import ROOM_ENTRY_QUERY from 'gql/queries/roomEntryQuery.gql';
import ROOM_ENTRY_FRAGMENT from 'gql/fragments/roomEntryParts.gql';
import UPDATE_ROOM_ENTRY_MUTATION from 'gql/mutations/rooms/updateRoomEntry.gql';
import ContentBlockForm from '@/components/content-block-form/ContentBlockForm';
import {ROOMS_FEATURE_SET} from '@/consts/features.consts';
import {ROOM_PAGE} from '@/router/room.names';
export default Vue.extend( {
props: {
slug: {
type: String,
required: true
},
entrySlug: {
type: String,
required: true
}
},
components: {
ContentBlockForm,
},
data() {
return {
features: ROOMS_FEATURE_SET,
roomEntry: {
title: '',
contents: [],
},
};
},
apollo: {
roomEntry: {
query: ROOM_ENTRY_QUERY,
variables() {
return {
slug: this.entrySlug
};
}
}
},
methods: {
goBack() {
this.$router.push({
name: ROOM_PAGE,
params: {
slug: this.slug
}
});
},
save({title, contents}) {
const entry = {
slug: this.roomEntry.slug,
title,
contents,
};
this.$apollo.mutate({
mutation: UPDATE_ROOM_ENTRY_MUTATION,
variables: {
input: {
roomEntry: entry,
}
},
update: (store, {data: {updateRoomEntry: {roomEntry}}}) => {
try {
const fragment = ROOM_ENTRY_FRAGMENT;
const id = store.identify(roomEntry);
const cachedEntry = store.readQuery({fragment, id});
const data = Object.assign({}, cachedEntry, roomEntry);
store.writeFragment({
id,
fragment,
data
});
} catch (e) {
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
}
}
}).then(() => {
this.goBack();
});
}
},
} );
</script>
<style scoped lang="scss">
@import '~styles/helpers';
</style>

View File

@ -52,7 +52,7 @@
const entry = { const entry = {
title, title,
contents, contents,
slug: this.slug roomSlug: this.slug
}; };
this.$apollo.mutate({ this.$apollo.mutate({
mutation: NEW_ROOM_ENTRY_MUTATION, mutation: NEW_ROOM_ENTRY_MUTATION,

View File

@ -2,3 +2,4 @@ export const NEW_ROOM_PAGE = 'new-room';
export const ROOMS_PAGE = 'rooms'; export const ROOMS_PAGE = 'rooms';
export const ROOM_PAGE = 'room'; export const ROOM_PAGE = 'room';
export const ADD_ROOM_ENTRY_PAGE = 'add-room-entry'; export const ADD_ROOM_ENTRY_PAGE = 'add-room-entry';
export const UPDATE_ROOM_ENTRY_PAGE = 'update-room-entry';

View File

@ -1,10 +1,11 @@
import {NEW_ROOM_PAGE, ROOMS_PAGE, ADD_ROOM_ENTRY_PAGE, ROOM_PAGE} from '@/router/room.names'; import {NEW_ROOM_PAGE, ROOMS_PAGE, ADD_ROOM_ENTRY_PAGE, ROOM_PAGE, UPDATE_ROOM_ENTRY_PAGE} from '@/router/room.names';
const rooms = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/rooms'); const rooms = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/rooms');
const newRoom = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/newRoom'); const newRoom = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/newRoom');
const editRoom = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/editRoom'); const editRoom = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/editRoom');
const room = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/room'); const room = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/room');
const newRoomEntry = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/newRoomEntry'); const newRoomEntry = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/newRoomEntry');
const editRoomEntry = () => import(/* webpackChunkName: "rooms" */'@/pages/rooms/editRoomEntry');
const moduleRoom = () => import(/* webpackChunkName: "rooms" */'@/pages/module/moduleRoom'); const moduleRoom = () => import(/* webpackChunkName: "rooms" */'@/pages/module/moduleRoom');
export default [ export default [
@ -13,6 +14,7 @@ export default [
{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_PAGE, component: room, props: true}, {path: '/room/:slug', name: ROOM_PAGE, component: room, props: true},
{path: '/room/:slug/add', name: ADD_ROOM_ENTRY_PAGE, component: newRoomEntry, props: true}, {path: '/room/:slug/add', name: ADD_ROOM_ENTRY_PAGE, component: newRoomEntry, props: true},
{path: '/room/:slug/edit/:entrySlug', name: UPDATE_ROOM_ENTRY_PAGE, component: editRoomEntry, props: true},
{ {
path: '/module-room/:slug', path: '/module-room/:slug',
name: 'moduleRoom', name: 'moduleRoom',

View File

@ -26,8 +26,8 @@ class RoomEntryArgument(InputObjectType):
class AddRoomEntryArgument(RoomEntryArgument): class AddRoomEntryArgument(RoomEntryArgument):
slug = graphene.String(required=True) room_slug = graphene.String(required=True)
class UpdateRoomEntryArgument(RoomEntryArgument): class UpdateRoomEntryArgument(RoomEntryArgument):
id = graphene.ID(required=True) slug = graphene.String(required=True)

View File

@ -86,13 +86,13 @@ class MutateRoomEntry(relay.ClientIDMutation):
def mutate_and_get_payload(cls, root, info, **kwargs): def mutate_and_get_payload(cls, root, info, **kwargs):
room_entry_data = kwargs.get('room_entry') room_entry_data = kwargs.get('room_entry')
room = None room = None
slug = room_entry_data.get('slug') room_slug = room_entry_data.get('room_slug')
if slug is not None: if room_slug is not None:
room = Room.objects.get(slug=slug) room = Room.objects.get(slug=room_slug)
room_entry_data['room'] = room.id room_entry_data['room'] = room.id
if room_entry_data.get('id') is not None: if room_entry_data.get('slug') is not None:
serializer = cls.update_room_entry(info, room_entry_data) serializer = cls.update_room_entry(info, room_entry_data)
else: else:
serializer = cls.add_room_entry(info, room_entry_data, room) serializer = cls.add_room_entry(info, room_entry_data, room)
@ -106,7 +106,7 @@ class MutateRoomEntry(relay.ClientIDMutation):
@classmethod @classmethod
def update_room_entry(cls, info, room_entry_data): def update_room_entry(cls, info, room_entry_data):
instance = get_object(RoomEntry, room_entry_data.get('id')) instance = RoomEntry.objects.get(slug=room_entry_data.get('slug'))
if not instance.room.school_class.is_user_in_schoolclass(info.context.user): if not instance.room.school_class.is_user_in_schoolclass(info.context.user):
raise Exception('You are in the wrong class') raise Exception('You are in the wrong class')

View File

@ -118,7 +118,7 @@ input AddRoomArgument {
input AddRoomEntryArgument { input AddRoomEntryArgument {
title: String! title: String!
contents: [ContentElementInput] contents: [ContentElementInput]
slug: String! roomSlug: String!
} }
input AddRoomEntryInput { input AddRoomEntryInput {