mirror of https://github.com/doccano/doccano.git
Hironsan
3 years ago
3 changed files with 274 additions and 3 deletions
Split View
Diff Options
-
141frontend/components/comment/Comment.vue
-
130frontend/components/comment/FormCreate.vue
-
6frontend/layouts/annotation.vue
@ -0,0 +1,141 @@ |
|||
<template> |
|||
<v-card class="elevation-0"> |
|||
<v-card-title> |
|||
<v-list-item class="grow ps-0"> |
|||
<v-list-item-avatar> |
|||
<v-icon large> |
|||
mdi-account-circle |
|||
</v-icon> |
|||
</v-list-item-avatar> |
|||
|
|||
<v-list-item-content> |
|||
<v-list-item-title>{{ comment.username }}</v-list-item-title> |
|||
<v-list-item-subtitle> |
|||
{{ comment.createdAt | dateParse('YYYY-MM-DDTHH:mm:ss') | dateFormat('DD/MM/YYYY HH:mm') }} |
|||
</v-list-item-subtitle> |
|||
</v-list-item-content> |
|||
|
|||
<v-row |
|||
align="center" |
|||
justify="end" |
|||
> |
|||
<v-menu |
|||
v-if="comment.user == userId" |
|||
bottom |
|||
left |
|||
> |
|||
<template v-slot:activator="{ on, attrs }"> |
|||
<v-btn |
|||
icon |
|||
v-bind="attrs" |
|||
v-on="on" |
|||
> |
|||
<v-icon>mdi-dots-vertical</v-icon> |
|||
</v-btn> |
|||
</template> |
|||
|
|||
<v-list> |
|||
<v-list-item> |
|||
<v-list-item-title |
|||
@click="showEdit=true" |
|||
> |
|||
Edit |
|||
</v-list-item-title> |
|||
</v-list-item> |
|||
<v-list-item> |
|||
<v-list-item-title |
|||
@click="$emit('delete-comment', comment)" |
|||
> |
|||
Delete |
|||
</v-list-item-title> |
|||
</v-list-item> |
|||
</v-list> |
|||
</v-menu> |
|||
</v-row> |
|||
</v-list-item> |
|||
</v-card-title> |
|||
|
|||
<v-card-text class="body-1"> |
|||
<span v-if="!showEdit"> |
|||
{{ comment.text }} |
|||
</span> |
|||
<v-form |
|||
v-else |
|||
v-model="valid" |
|||
> |
|||
<v-row> |
|||
<v-textarea |
|||
v-model="editText" |
|||
auto-grow |
|||
rows="1" |
|||
solo |
|||
:rules="commentRules" |
|||
/> |
|||
</v-row> |
|||
<v-row justify="end"> |
|||
<v-btn |
|||
text |
|||
class="text-capitalize" |
|||
@click="cancel" |
|||
> |
|||
Cancel |
|||
</v-btn> |
|||
<v-btn |
|||
:disabled="!valid" |
|||
color="primary" |
|||
class="text-capitalize" |
|||
@click="updateComment(editText)" |
|||
> |
|||
Update |
|||
</v-btn> |
|||
</v-row> |
|||
</v-form> |
|||
</v-card-text> |
|||
<v-divider /> |
|||
</v-card> |
|||
</template> |
|||
|
|||
<script> |
|||
import Vue from 'vue' |
|||
import VueFilterDateFormat from '@vuejs-community/vue-filter-date-format' |
|||
import VueFilterDateParse from '@vuejs-community/vue-filter-date-parse' |
|||
import { CommentItem } from '@/models/comment' |
|||
import { UserItem } from '../../models/user'; |
|||
Vue.use(VueFilterDateFormat) |
|||
Vue.use(VueFilterDateParse) |
|||
|
|||
export default { |
|||
name: 'Comment', |
|||
props: { |
|||
comment: { |
|||
required: true, |
|||
type: Object |
|||
}, |
|||
userId: { |
|||
required: true, |
|||
type: Number |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
showEdit: false, |
|||
editText: this.comment.text, |
|||
commentRules: [ |
|||
v => !!v.trim() || 'Comment is required' |
|||
], |
|||
valid: false |
|||
} |
|||
}, |
|||
methods: { |
|||
updateComment(newText) { |
|||
this.showEdit = false |
|||
const comment = CommentItem.valueOf({...this.comment, text:newText }) |
|||
this.$emit('update-comment', comment) |
|||
}, |
|||
cancel() { |
|||
this.showEdit = false |
|||
this.editText = this.comment.text |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,130 @@ |
|||
<template> |
|||
<div style="display:inline;"> |
|||
<v-tooltip bottom> |
|||
<template v-slot:activator="{ on }"> |
|||
<v-btn |
|||
class="text-capitalize ps-1 pe-1" |
|||
min-width="36" |
|||
icon |
|||
v-on="on" |
|||
@click="dialog=true" |
|||
> |
|||
<v-icon> |
|||
mdi-chat |
|||
</v-icon> |
|||
</v-btn> |
|||
</template> |
|||
<span>{{ $t('annotation.commentTooltip') }}</span> |
|||
</v-tooltip> |
|||
<v-dialog |
|||
v-model="dialog" |
|||
width="800" |
|||
> |
|||
<base-card |
|||
:title="$t('comments.comments')" |
|||
:cancel-text="$t('generic.close')" |
|||
@cancel="dialog=false" |
|||
> |
|||
<template #content> |
|||
<v-form v-model="valid"> |
|||
<v-textarea |
|||
v-model="message" |
|||
auto-grow |
|||
hide-details |
|||
outlined |
|||
rows="1" |
|||
name="CommentInput" |
|||
:label="$t('comments.message')" |
|||
:rules="commentRules" |
|||
/> |
|||
<v-btn |
|||
class="white--text text-capitalize mt-3" |
|||
color="primary" |
|||
depressed |
|||
:disabled="!valid" |
|||
@click="add" |
|||
> |
|||
{{ $t('comments.send') }} |
|||
</v-btn> |
|||
</v-form> |
|||
<comment |
|||
v-for="comment in comments" |
|||
:key="comment.id" |
|||
:comment="comment" |
|||
:user-id="user.id" |
|||
@delete-comment="remove" |
|||
@update-comment="maybeUpdate" |
|||
/> |
|||
</template> |
|||
</base-card> |
|||
</v-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import Vue from 'vue' |
|||
import { mapGetters } from 'vuex' |
|||
import BaseCard from '@/components/molecules/BaseCard.vue' |
|||
import { CommentItem } from '@/models/comment' |
|||
import Comment from './Comment.vue' |
|||
import { CommentReadDTO } from '~/services/application/comment.service' |
|||
|
|||
export default Vue.extend({ |
|||
components: { |
|||
BaseCard, |
|||
Comment |
|||
}, |
|||
|
|||
async fetch() { |
|||
this.user = await this.$services.user.getMyProfile() |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
dialog: false, |
|||
user: {}, |
|||
comments: [] as CommentReadDTO[], |
|||
commentRules: [ |
|||
(v: string) => !!v.trim() || 'Comment is required' |
|||
], |
|||
message: '', |
|||
valid: false |
|||
} |
|||
}, |
|||
|
|||
computed: { |
|||
...mapGetters('documents', ['currentDoc']) |
|||
}, |
|||
|
|||
watch: { |
|||
currentDoc: { |
|||
handler(val) { |
|||
if (val !== undefined) { |
|||
this.list() |
|||
} |
|||
}, |
|||
immediate: true, |
|||
deep: true |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
async list() { |
|||
this.comments = await this.$services.comment.list(this.$route.params.id, this.currentDoc.id) |
|||
}, |
|||
async add() { |
|||
await this.$services.comment.create(this.$route.params.id, this.currentDoc.id, this.message) |
|||
this.list() |
|||
this.message = '' |
|||
}, |
|||
async remove(item: CommentItem) { |
|||
await this.$services.comment.delete(this.$route.params.id, this.currentDoc.id, item) |
|||
this.list() |
|||
}, |
|||
async maybeUpdate(item: CommentItem) { |
|||
await this.$services.comment.update(this.$route.params.id, this.currentDoc.id, item) |
|||
this.list() |
|||
} |
|||
} |
|||
}) |
|||
</script> |
Write
Preview
Loading…
Cancel
Save