Skip to content

Instantly share code, notes, and snippets.

@LTroya
Last active June 26, 2017 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LTroya/e6b5907736be66dee750f44a4b080edf to your computer and use it in GitHub Desktop.
Save LTroya/e6b5907736be66dee750f44a4b080edf to your computer and use it in GitHub Desktop.
Revision - Reply components using Vue and Vuex
<template>
<div class="row">
<div class="col-md-10 col-md-offset-1 pb-20">
<form id="new-revision" class="new-revision" v-on:submit.prevent="submit">
<div class="form-group">
<textarea name="body" id="body" rows="4" class="form-control" placeholder="Do you have something to say?" v-model="form.body"></textarea>
</div>
<button type="submit" class="btn btn-primary" :disabled="isSubmitting">Add Revision</button>
<button type="button" class="btn btn-link" @click="hideReply" v-if="revision" :disabled="isSubmitting">Cancel</button>
<a class="pull-right clip" data-toggle="modal" data-target="#attachment-modal">
<img src="/img/site/checkout_success_clip.svg" alt="Clip"> Attachments
</a>
<div class="file--upload__uploaded"></div>
</form>
</div>
</div>
</template>
<script>
export default {
props: ['task', 'revision', 'action'],
mounted() {
if (this.action === 'update') this.form.body = this.revision.body;
},
data() {
return {
form: {
body: '',
parent_id: this.revision ? this.revision.id : null
},
isSubmitting: false
}
},
computed: {
endpoint() {
return `/dashboard/tasks/${this.task.id}/revisions`;
},
updateEnpoint() {
return `${this.endpoint}/${this.revision.id}`;
}
},
methods: {
submit() {
this.isSubmitting = true;
if (!this.form.body) return;
this.save()
.then(this.onSuccess)
.catch(this.onError)
.finally(() => this.isSubmitting = false)
},
save() {
return this.action === 'update'
? axios.put(this.updateEnpoint, this.form)
: axios.post(this.endpoint, this.form);
},
onSuccess({data}) {
this.dispatch(data);
this.form = {};
this.alert();
},
dispatch(data) {
if (this.revision) {
this.updateStore(data);
this.hideReply();
return;
}
this.$store.dispatch('addRevision', data.revision);
},
updateStore(data) {
if (this.action === 'update') {
this.$store.dispatch('updateReply', data.revision);
return;
}
this.$store.dispatch('addReply', {
revision: this.revision,
reply: data.revision
});
},
alert() {
if (this.revision) {
successToast('Your reply has been added');
return;
}
successToast('Your revision has been added');
},
onError(err) {
console.log("Err", err);
},
hideReply() {
if (this.revision) this.$emit(`hide`);
}
}
}
</script>
<template>
<div class="main-comment">
<div v-if="editing">
<add-revision :task="task" :revision="revision" action="update" @hide="editing = false"></add-revision>
</div>
<div class="comment" :id="id" v-else>
<div class="col-md-12">
<div class="text-center comment-avatar">
<img :src="revision.user.photo_url" :alt="revision.user.name" class="img-circle" style="max-height: 60px;">
</div>
<div class="br5 comment-box">
<div class="comment bg-white">
<div class="author bold">
{{ revision.user.name }}
<span class="timestamp regular">{{ revision.created_at | relative }}</span>
</div>
{{ revision.body }}
</div>
<div class="col-md-12">
<!-- data-task-type="{{ $task->task_type }}" data-parent-id="{{ $revision->id }} -->
<p class="pull-right comment-reply" @click="show = true" v-if="showReply">
<img src="/img/site/icons/enter.svg" alt="Reply"> Reply
</p>
<p class="pull-right comment-reply" @click="editing = true" v-else>
<i class="glyphicon glyphicon-pencil" alt="Edit"></i> Edit
</p>
</div>
</div>
</div>
</div>
<div v-if="show">
<add-revision :task="task" :revision="revision" action="create" @hide="show = false"></add-revision>
</div>
<div class="sub-comments-container">
<div v-for="reply in revision.children" :key="reply.id">
<reply :data="reply" :task="task"></reply>
</div>
</div>
</div>
</template>
<script>
import Reply from './Reply.vue';
export default {
props: ['data', 'task'],
components: {Reply},
data() {
return {
revision: this.data,
show: false,
editing: false
}
},
computed: {
id() {
return `revision-${this.revision.id}`;
},
showReply() {
return Kapa.user.id !== this.revision.user.id;
}
}
}
</script>
<style>
.comment-reply {
cursor: pointer;
}
</style>
<script>
import Revision from './Revision.vue';
export default {
props: ['task'],
components: {Revision},
mounted() {
this.$store.dispatch('setRevisions', this.task.revisions);
},
computed: {
revisions() {
return this.$store.state.revisions;
}
}
}
</script>
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
revisions: [],
revision: {}
},
mutations: {
SET_REVISIONS (state, revisions) {
state.revisions = revisions;
},
SET_REVISION (state, revision) {
state.revision = revision;
},
ADD_REVISION (state, revision) {
state.revisions.unshift(revision);
},
ADD_REPLY (state, {revision: rev, reply}) {
let revision = state.revisions.find(value => value.id === rev.id);
revision.children.push(reply);
},
UPDATE_REPLY (state, rev) {
let index = state.revisions.findIndex(value => value.id === rev.id);
// Vue.set(state.revisions, index, rev);
let deleted = state.revisions.splice(index, 1, rev);
}
},
actions: {
setRevisions({commit}, revisions) {
commit('SET_REVISIONS', revisions);
},
setRevision({commit}, revision) {
commit('SET_REVISION', revision);
},
addRevision({commit}, revision) {
commit('ADD_REVISION', revision);
},
addReply({commit}, payload) {
commit('ADD_REPLY', payload);
},
updateReply({commit}, reply) {
commit('UPDATE_REPLY', reply)
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment