From 57f78ee0d411d24b08bade12906f9be405554293 Mon Sep 17 00:00:00 2001 From: konrad Date: Tue, 25 Feb 2020 20:11:36 +0000 Subject: [PATCH] Task Comments (#66) Better edit/remove buttons Spacing More loading Add loading Better dates formatting Add editing comments Move closing delete modal to finally Add delete comments Add keycode modifier Comment styling Comment form Add basic task comments functionality Co-authored-by: kolaente Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/66 --- src/components/tasks/TaskDetailView.vue | 5 + src/components/tasks/reusable/comments.vue | 177 +++++++++++++++++++++ src/main.js | 2 + src/models/taskComment.js | 22 +++ src/models/user.js | 3 +- src/services/taskComment.js | 25 +++ src/styles/components/_all.scss | 1 + src/styles/components/comments.scss | 19 +++ src/styles/theme/theme.scss | 8 + 9 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 src/components/tasks/reusable/comments.vue create mode 100644 src/models/taskComment.js create mode 100644 src/services/taskComment.js create mode 100644 src/styles/components/comments.scss diff --git a/src/components/tasks/TaskDetailView.vue b/src/components/tasks/TaskDetailView.vue index 87c941004..e21f944cd 100644 --- a/src/components/tasks/TaskDetailView.vue +++ b/src/components/tasks/TaskDetailView.vue @@ -190,6 +190,9 @@ ref="relatedTasks" /> + + +
@@ -288,6 +291,7 @@ import RelatedTasks from './reusable/relatedTasks' import RepeatAfter from './reusable/repeatAfter' import Reminders from './reusable/reminders' + import Comments from './reusable/comments' import router from '../../router' export default { @@ -301,6 +305,7 @@ EditLabels, PercentDoneSelect, PrioritySelect, + Comments, flatPickr, }, data() { diff --git a/src/components/tasks/reusable/comments.vue b/src/components/tasks/reusable/comments.vue new file mode 100644 index 000000000..b59714a6d --- /dev/null +++ b/src/components/tasks/reusable/comments.vue @@ -0,0 +1,177 @@ + + + diff --git a/src/main.js b/src/main.js index 41c642ac2..a3eccf5ac 100644 --- a/src/main.js +++ b/src/main.js @@ -64,6 +64,7 @@ import { faClock } from '@fortawesome/free-regular-svg-icons' import { faHistory } from '@fortawesome/free-solid-svg-icons' import { faSearch } from '@fortawesome/free-solid-svg-icons' import { faCheckDouble } from '@fortawesome/free-solid-svg-icons' +import { faComments } from '@fortawesome/free-regular-svg-icons' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' library.add(faSignOutAlt) @@ -102,6 +103,7 @@ library.add(faClock) library.add(faHistory) library.add(faSearch) library.add(faCheckDouble) +library.add(faComments) Vue.component('icon', FontAwesomeIcon) diff --git a/src/models/taskComment.js b/src/models/taskComment.js new file mode 100644 index 000000000..63c4455d6 --- /dev/null +++ b/src/models/taskComment.js @@ -0,0 +1,22 @@ +import AbstractModel from './abstractModel' +import UserModel from './user' + +export default class TaskCommentModel extends AbstractModel { + constructor(data) { + super(data) + this.author = new UserModel(this.author) + this.created = new Date(this.created) + this.updated = new Date(this.updated) + } + + defaults() { + return { + id: 0, + task_id: 0, + comment: '', + author: UserModel, + created: null, + update: null, + } + } +} diff --git a/src/models/user.js b/src/models/user.js index 380a17b72..d06abccf5 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -19,6 +19,7 @@ export default class UserModel extends AbstractModel { } getAvatarUrl(size = 50) { - return `https://www.gravatar.com/avatar/${this.avatar}?s=${size}&d=mp` + const avatarUrl = this.avatar !== '' ? this.avatar : this.avatarUrl + return `https://www.gravatar.com/avatar/${avatarUrl}?s=${size}&d=mp` } } \ No newline at end of file diff --git a/src/services/taskComment.js b/src/services/taskComment.js new file mode 100644 index 000000000..bcd74ed25 --- /dev/null +++ b/src/services/taskComment.js @@ -0,0 +1,25 @@ +import AbstractService from './abstractService' +import TaskCommentModel from '../models/taskComment' +import moment from 'moment' + +export default class TaskCommentService extends AbstractService { + constructor() { + super({ + create: '/tasks/{task_id}/comments', + getAll: '/tasks/{task_id}/comments', + get: '/tasks/{task_id}/comments/{id}', + update: '/tasks/{task_id}/comments/{id}', + delete: '/tasks/{task_id}/comments/{id}', + }) + } + + processModel(model) { + model.created = moment(model.created).toISOString() + model.updated = moment(model.updated).toISOString() + return model + } + + modelFactory(data) { + return new TaskCommentModel(data) + } +} \ No newline at end of file diff --git a/src/styles/components/_all.scss b/src/styles/components/_all.scss index bf427a129..6b2bd971f 100644 --- a/src/styles/components/_all.scss +++ b/src/styles/components/_all.scss @@ -12,3 +12,4 @@ @import 'tasks'; @import 'teams'; @import 'migrator'; +@import 'comments'; diff --git a/src/styles/components/comments.scss b/src/styles/components/comments.scss new file mode 100644 index 000000000..6fd3c4f48 --- /dev/null +++ b/src/styles/components/comments.scss @@ -0,0 +1,19 @@ +.media.comment{ + align-items: center; + + .media-left { + margin: 0 1em; + } + + .comment-actions { + font-size: .8em; + + &, a { + color: $grey; + } + + a:hover { + text-decoration: underline; + } + } +} \ No newline at end of file diff --git a/src/styles/theme/theme.scss b/src/styles/theme/theme.scss index 0f5f2035b..75fd1a9fc 100644 --- a/src/styles/theme/theme.scss +++ b/src/styles/theme/theme.scss @@ -30,3 +30,11 @@ h1,h2,h3,h4,h5,h6{ .has-no-border{ border: none !important; } + +.has-rounded-corners { + border-radius: $radius; +} + +.image.is-avatar{ + border-radius: 100%; +}