fix autosave of comment

This commit is contained in:
Julien Fastré 2022-03-14 13:04:29 +01:00
parent fc1fe7c277
commit bd79391efc
3 changed files with 131 additions and 58 deletions

View File

@ -1,17 +1,22 @@
/** /**
* Generic api method that can be adapted to any fetch request * Generic api method that can be adapted to any fetch request
*/ */
const makeFetch = (method, url, body) => { const makeFetch = (method, url, body, options) => {
return fetch(url, { let opts = {
method: method, method: method,
headers: { headers: {
'Content-Type': 'application/json;charset=utf-8' 'Content-Type': 'application/json;charset=utf-8'
}, },
body: (body !== null) ? JSON.stringify(body) : null body: (body !== null) ? JSON.stringify(body) : null
}) };
if (typeof options !== 'undefined') {
opts = Object.assign(opts, options);
}
return fetch(url, opts)
.then(response => { .then(response => {
if (response.ok) { if (response.ok) {
console.log('200 error')
return response.json(); return response.json();
} }

View File

@ -17,12 +17,11 @@
:placeholder="$t('comment.content')" :placeholder="$t('comment.content')"
:editor="editor" :editor="editor"
v-model="content" v-model="content"
@input="onContentChange"
tag-name="textarea"> tag-name="textarea">
</ckeditor> </ckeditor>
<div class="sub-comment"> <div class="sub-comment">
<div v-if="pinnedComment" class="metadata"> <div v-if="pinnedComment !== null && typeof pinnedComment.creator !== 'undefined'" class="metadata">
{{ $t('comment.created_by', [ {{ $t('comment.created_by', [
pinnedComment.creator.text, pinnedComment.creator.text,
$d(pinnedComment.updatedAt.datetime, 'long') $d(pinnedComment.updatedAt.datetime, 'long')
@ -64,11 +63,8 @@ export default {
data() { data() {
return { return {
editor: ClassicEditor, editor: ClassicEditor,
formData: { loading: false,
type: "accompanying_period_comment", lastRecordedContent: null,
content: ''
},
loading: false
} }
}, },
computed: { computed: {
@ -77,10 +73,48 @@ export default {
}), }),
content: { content: {
set(value) { set(value) {
this.formData.content = value; console.log('new comment value', value);
console.log('previous value', this.lastRecordedContent);
this.lastRecordedContent = value;
setTimeout(() => {
console.log('performing test on ', value);
if (this.lastRecordedContent === value) {
this.loading = true;
if (value !== '') {
this.$store.dispatch('updatePinnedComment', value)
.then(() => {
this.loading = false;
})
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
} else {
if (this.$store.state.accompanyingCourse.pinnedComment !== null) {
this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id})
.then(() => {
this.loading = false;
this.lastRecoredContent = null;
})
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
}
}
}
}, 3000);
}, },
get() { get() {
return this.pinnedComment ? this.pinnedComment.content : ''; return this.pinnedComment ? this.pinnedComment.content : '';
} }
}, },
errors() { errors() {
@ -89,38 +123,7 @@ export default {
}, },
methods: { methods: {
onContentChange() { onContentChange() {
this.loading = true;
let lastRecordedContent = this.formData.content; let lastRecordedContent = this.formData.content;
setTimeout(() => {
if (this.formData.content !== '') {
if (lastRecordedContent === this.formData.content) {
if (this.pinnedComment) {
let body = this.formData;
Object.assign(body, {id: this.pinnedComment.id});
this.$store.dispatch('updatePinnedComment', body)
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
} else {
this.$store.dispatch('addPinnedComment', this.formData)
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
}
lastRecordedContent = null;
}
}
this.loading = false;
}, 3000);
}, },
removeComment() { removeComment() {
this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id}) this.$store.dispatch('removePinnedComment', {id: this.pinnedComment.id})

View File

@ -42,7 +42,11 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
referrersSuggested: [], referrersSuggested: [],
// all the users available // all the users available
users: [], users: [],
permissions: {} permissions: {},
// controller for updating comment
updateCommentAbortController: null,
// waiting response for inserting first comment
postFirstPinnedCommentResponse: null,
}, },
getters: { getters: {
isParticipationValid(state) { isParticipationValid(state) {
@ -203,12 +207,36 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
//console.log('### mutation: toggleConfidential'); //console.log('### mutation: toggleConfidential');
state.accompanyingCourse.confidential = value; state.accompanyingCourse.confidential = value;
}, },
addPinnedComment(state, value) { setPinnedComment(state, content) {
state.accompanyingCourse.pinnedComment = value; if (null === state.accompanyingCourse.pinnedComment) {
state.accompanyingCourse.pinnedComment = {
id: -1,
content,
type: "accompanying_period_comment",
};
} else {
state.accompanyingCourse.pinnedComment.content = content;
}
},
setPinnedCommentDetails(state, value) {
state.accompanyingCourse.pinnedComment.id = value.id;
if (typeof value.creator !== 'undefined') {
state.accompanyingCourse.pinnedComment.creator = value.creator;
state.accompanyingCourse.pinnedComment.updatedBy = value.updatedBy;
state.accompanyingCourse.pinnedComment.updatedAt = value.updatedAt;
state.accompanyingCourse.pinnedComment.createdAt = value.createdAt;
}
}, },
removePinnedComment(state, value) { removePinnedComment(state, value) {
state.accompanyingCourse.pinnedComment = null; state.accompanyingCourse.pinnedComment = null;
}, },
setPinCommentAbortController(state, value) {
state.updateCommentAbortController = value;
},
setPostFirstPinnedCommentResponse(state, value) {
state.postFirstPinnedCommentResponse = value;
},
updateSocialIssues(state, value) { updateSocialIssues(state, value) {
console.log('updateSocialIssues', value); console.log('updateSocialIssues', value);
state.accompanyingCourse.socialIssues = value; state.accompanyingCourse.socialIssues = value;
@ -355,28 +383,68 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
throw error; throw error;
}) })
}, },
addPinnedComment({ commit, dispatch }, payload) { /**
const body = payload ? { type: payload.type, content: payload.content } : {}; * internal method to insert a new comment
*
* @param commit
* @param dispatch
* @param content
* @returns {*}
*/
addPinnedComment({ commit, dispatch }, content) {
const url = `/api/1.0/person/accompanying-course/${id}/comment.json`; const url = `/api/1.0/person/accompanying-course/${id}/comment.json`;
return makeFetch('POST', url, body) return makeFetch('POST', url, {type: "accompanying_period_comment", content})
.then((response) => { .then((response) => {
dispatch('patchFirstComment', response); commit('setPinnedCommentDetails', response);
return dispatch('patchFirstComment', response);
}) })
.catch((error) => { .catch((error) => {
commit('catchError', error); commit('catchError', error);
throw error; throw error;
}) })
}, },
updatePinnedComment({ commit }, payload) { updatePinnedComment({ commit, state, dispatch }, content) {
commit('setPinnedComment', content);
if (state.accompanyingCourse.pinnedComment.id === -1 && state.postFirstPinnedCommentResponse === null) {
let r = dispatch('addPinnedComment', content).then(() => {
commit('setPostFirstPinnedCommentResponse', null);
});
commit('setPostFirstPinnedCommentResponse', r);
} else {
(state.postFirstPinnedCommentResponse === null ? Promise.resolve() : state.postFirstPinnedCommentResponse).then(() => {
dispatch('updateExistingPinnedComment', content);
});
}
},
/**
* internal method to patch an existing comment
*
* @param commit
* @param state
* @param comment
* @returns {*}
*/
updateExistingPinnedComment({ commit, state }, content) {
const payload = {type: "accompanying_period_comment", content, id: state.accompanyingCourse.pinnedComment.id};
const url = `/api/1.0/person/accompanying-period/comment/${payload.id}.json`; const url = `/api/1.0/person/accompanying-period/comment/${payload.id}.json`;
return makeFetch('PATCH', url, payload) if (state.updateCommentAbortController !== null) {
state.updateCommentAbortController.abort();
commit('setPinCommentAbortController', null);
}
let controller = new AbortController();
commit('setPinCommentAbortController', controller);
return makeFetch('PATCH', url, payload, { signal: controller.signal })
.then((response) => { .then((response) => {
commit('addPinnedComment', response); commit('setPinCommentAbortController', null);
commit('setPinnedCommentDetails', response);
}) })
.catch((error) => { .catch((error) => {
commit('catchError', error); commit('catchError', error);
commit('setPinCommentAbortController', null);
throw error; throw error;
}) })
}, },
@ -659,9 +727,6 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
} }
}; };
return makeFetch('PATCH', url, body) return makeFetch('PATCH', url, body)
.then((response) => {
commit('addPinnedComment', response.pinnedComment);
})
.catch((error) => { .catch((error) => {
commit('catchError', error); commit('catchError', error);
throw error; throw error;