diff --git a/Dockerfile b/Dockerfile index 98400857..bf14c398 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,9 +46,9 @@ RUN pip install --no-cache-dir -U pip \ && rm -rf /deps COPY --chown=doccano:doccano . /doccano -WORKDIR /doccano +WORKDIR /doccano/app COPY --from=frontend-builder /frontend/dist /doccano/app/client/dist -RUN python app/manage.py collectstatic --noinput +RUN python manage.py collectstatic --noinput VOLUME /data ENV DATABASE_URL="sqlite:////data/doccano.db" @@ -61,7 +61,6 @@ ENV GOOGLE_TRACKING_ID="" ENV AZURE_APPINSIGHTS_IKEY="" USER doccano -WORKDIR /doccano EXPOSE ${PORT} CMD ["/doccano/tools/run.sh"] diff --git a/app/api/migrations/0004_merge_20210114_1117.py b/app/api/migrations/0004_merge_20210114_1117.py new file mode 100644 index 00000000..881e8b55 --- /dev/null +++ b/app/api/migrations/0004_merge_20210114_1117.py @@ -0,0 +1,14 @@ +# Generated by Django 3.1.5 on 2021-01-14 11:17 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0002_comment'), + ('api', '0003_merge_20200612_0205'), + ] + + operations = [ + ] diff --git a/app/api/serializers.py b/app/api/serializers.py index 0acb47e6..78444cc1 100644 --- a/app/api/serializers.py +++ b/app/api/serializers.py @@ -7,7 +7,7 @@ from rest_framework.exceptions import ValidationError from .models import Label, Project, Document, RoleMapping, Role, Comment -from .models import TextClassificationProject, SequenceLabelingProject, Seq2seqProject +from .models import TextClassificationProject, SequenceLabelingProject, Seq2seqProject, Speech2textProject from .models import DocumentAnnotation, SequenceAnnotation, Seq2seqAnnotation, Speech2textAnnotation diff --git a/frontend/components/containers/annotation/CommentButton.vue b/frontend/components/containers/annotation/CommentButton.vue new file mode 100644 index 00000000..074c3744 --- /dev/null +++ b/frontend/components/containers/annotation/CommentButton.vue @@ -0,0 +1,158 @@ + + + diff --git a/frontend/i18n/en/projects/annotation.js b/frontend/i18n/en/projects/annotation.js index 7e893b5d..de88642b 100644 --- a/frontend/i18n/en/projects/annotation.js +++ b/frontend/i18n/en/projects/annotation.js @@ -7,6 +7,8 @@ export default { filterOption3: 'Undone', guidelineTooltip: 'Show Guideline', guidelinePopupTitle: 'Annotation Guideline', + commentTooltip: 'Click to comment on document', + commentPopupTitle: 'Comment', metadataDefaultMessage: 'No data available', key: 'Key', value: 'Value', diff --git a/frontend/layouts/annotation.vue b/frontend/layouts/annotation.vue index a49f76d8..b964b4ec 100644 --- a/frontend/layouts/annotation.vue +++ b/frontend/layouts/annotation.vue @@ -39,6 +39,7 @@ v-model="filterOption" /> + @@ -79,6 +80,7 @@ import GuidelineButton from '@/components/containers/annotation/GuidelineButton' import MetadataBox from '@/components/organisms/annotation/MetadataBox' import FilterButton from '@/components/containers/annotation/FilterButton' import ApproveButton from '@/components/containers/annotation/ApproveButton' +import CommentButton from '@/components/containers/annotation/CommentButton' import Pagination from '~/components/containers/annotation/Pagination' import TheHeader from '~/components/organisms/layout/TheHeader' import TheSideBar from '~/components/organisms/layout/TheSideBar' @@ -95,7 +97,8 @@ export default { FilterButton, ApproveButton, MetadataBox, - ClearAnnotationsButton + ClearAnnotationsButton, + CommentButton }, fetch() { diff --git a/frontend/services/comment.service.js b/frontend/services/comment.service.js new file mode 100644 index 00000000..369e8f52 --- /dev/null +++ b/frontend/services/comment.service.js @@ -0,0 +1,26 @@ +import ApiService from '@/services/api.service' + +class CommentService { + constructor() { + this.request = ApiService + } + + getCommentList({ projectId, docId }) { + return this.request.get(`/projects/${projectId}/docs/${docId}/comments`) + } + + addComment(projectId, docId, payload) { + console.log(payload) + return this.request.post(`/projects/${projectId}/docs/${docId}/comments`, payload) + } + + deleteComment(projectId, docId, commentId) { + return this.request.delete(`/projects/${projectId}/docs/${docId}/comments/${commentId}`) + } + + updateComment(projectId, docId, commentId, payload) { + return this.request.patch(`/projects/${projectId}/docs/${docId}/comments/${commentId}`, payload) + } +} + +export default new CommentService() diff --git a/frontend/store/documents.js b/frontend/store/documents.js index 287e7d56..79220f52 100644 --- a/frontend/store/documents.js +++ b/frontend/store/documents.js @@ -1,3 +1,4 @@ +import CommentService from '@/services/comment.service' import DocumentService from '@/services/document.service' import AnnotationService from '@/services/annotation.service' @@ -73,6 +74,16 @@ export const mutations = { const item = state.items[state.current].annotations.find(item => item.id === payload.id) Object.assign(item, payload) }, + addComment(state, payload) { + state.items[state.current].comments.push(payload) + }, + updateComment(state, payload) { + const item = state.items[state.current].comments.find(item => item.id === payload.id) + Object.assign(item, payload) + }, + deleteComment(state, commentId) { + state.items[state.current].comments = state.items[state.current].comments.filter(item => item.id !== commentId) + }, updateSearchOptions(state, payload) { state.searchOptions = Object.assign(state.searchOptions, payload) }, @@ -222,5 +233,35 @@ export const actions = { .catch((error) => { alert(error) }) + }, + addComment({ commit, state }, payload) { + const documentId = state.items[state.current].id + CommentService.addComment(payload.projectId, documentId, payload) + .then((response) => { + commit('addComment', response.data) + }) + .catch((error) => { + alert(error) + }) + }, + updateComment({ commit, state }, payload) { + const documentId = state.items[state.current].id + CommentService.updateComment(payload.projectId, documentId, payload.commentId, payload) + .then((response) => { + commit('updateComment', response.data) + }) + .catch((error) => { + alert(error) + }) + }, + deleteComment({ commit, state }, payload) { + const documentId = state.items[state.current].id + CommentService.deleteComment(payload.projectId, documentId, payload.commentId) + .then((response) => { + commit('deleteComment', payload.commentId) + }) + .catch((error) => { + alert(error) + }) } }