Skip to content

Commit

Permalink
more consistent comment component
Browse files Browse the repository at this point in the history
  • Loading branch information
blockisec committed Feb 4, 2024
1 parent ea72a28 commit c73d605
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 60 deletions.
81 changes: 81 additions & 0 deletions frontend/src/components/elements/CommentCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<script>
import MarkdownEditor from '@/components/forms/MarkdownEditor.vue';
export default {
name: 'CommentCard',
props: {
author: {
required: true
},
date: {
required: true
},
comment: {
required: true
},
editedBy: {
required: false
}
},
emit: ['comment-edited'],
data() {
return {
editMode: false,
editedComment: this.comment,
items: [
{
label: 'Edit',
icon: 'fa fa-edit',
command: () => {
this.editMode = !this.editMode;
}
}
]
};
},
methods: {
toggle(event) {
this.$refs.menu.toggle(event);
},
onCommentEdited() {
this.$emit('comment-edited', this.editedComment);
this.editMode = false;
}
},
components: { MarkdownEditor }
};
</script>

<template>
<Card class="card p-0 surface-ground border-200 border-1 border-round mt-3">
<template #header>
<div class="col-12 surface-card border-bottom-1 border-200">
<div class="grid">
<div class="col-10">
<div class="flex justify-content-start">{{ author }} commented on {{ date }}</div>
</div>
<div class="col-2">
<div class="flex justify-content-end">
<Button size="small" text type="button" class="text-color p-1" icon="fa fa-ellipsis" @click="toggle" aria-haspopup="true" aria-controls="comment_edit_menu" />
<Menu ref="menu" id="comment_edit_menu" :model="items" :popup="true"></Menu>
</div>
</div>
<div class="col-12 mt-0 pt-0 pb-0 mb-0" v-if="editedBy">
<small>edited by {{ editedBy }}</small>
</div>
</div>
</div>
</template>
<template #content>
<div class="grid">
<div class="col-12" v-if="editMode !== true">
{{ comment }}
</div>
<div class="col-12" v-else>
<MarkdownEditor v-model="editedComment"></MarkdownEditor>
<Button label="Save" @click="onCommentEdited"></Button>
</div>
</div>
</template>
</Card>
</template>
5 changes: 5 additions & 0 deletions frontend/src/service/FindingService.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ export default class FindingService {
return api.post(url, data);
}

patchComment(api, projectId, findingId, commentId, data) {
let url = `/projects/${projectId}/findings/${findingId}/comments/${commentId}/`;
return api.patch(url, data);
}

getTimeline(projectId, findingId) {
let url = '/projects/' + projectId + '/findings/' + findingId + '/timelines/';
return api.get(url);
Expand Down
67 changes: 26 additions & 41 deletions frontend/src/views/pages/advisories/CommentList.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script>
import AdvisoryService from '@/service/AdvisoryService';
import AdvisoryTabMenu from '../../../components/pages/AdvisoryTabMenu.vue';
import MarkdownEditor from '@/components/forms/MarkdownEditor.vue';
import BlankSlate from '@/components/BlankSlate.vue';
import AdvisoryCommentCreateDialog from '@/components/advisories/AdvisoryCommentCreateDialog.vue';
import CommentCard from '@/components/elements/CommentCard.vue';
export default {
name: 'CommentList',
Expand Down Expand Up @@ -33,7 +33,7 @@ export default {
}
],
advisoryId: this.$route.params.advisoryId,
items: [],
items: []
};
},
mounted() {
Expand All @@ -45,19 +45,20 @@ export default {
this.items = response.data.results;
});
},
onClickEditComment(comment) {
this.activeEditableComment = comment;
this.activeEditableComment.editMode = !this.activeEditableComment.editMode;
if (!this.activeEditableComment.editMode) {
this.activeEditableComment = null;
}
patchComment(pk, comment) {
let data = { comment: comment };
this.service.patchComment(this.$api, this.advisoryId, pk, data).then(() => {
this.getItems();
});
},
patchComment(comment) {
let data = { comment: comment.comment };
this.service.patchComment(this.$api, this.advisoryId, comment.pk, data);
getUserEditUsername(comment) {
if (comment.user_edit) {
return comment.user_edit.username;
}
return comment.user_edit;
}
},
components: { AdvisoryCommentCreateDialog, AdvisoryTabMenu, MarkdownEditor, BlankSlate }
components: { CommentCard, AdvisoryCommentCreateDialog, AdvisoryTabMenu, BlankSlate }
};
</script>

Expand All @@ -82,35 +83,19 @@ export default {
<div class="col-12">
<AdvisoryTabMenu class="surface-card"></AdvisoryTabMenu>
<div class="card border-noround-top" v-if="items.length > 0">
<Card v-for="comment in items" :key="comment.pk" class="surface-ground border-200 border-1 border-round mt-3">
<template #header>
<div class="col-12 surface-card border-200 border-1 border-round">
<div class="grid">
<div class="col-10">
<div class="flex justify-content-start">
{{ comment.user.username }} commented on
{{ comment.date_created }}
</div>
</div>
<div class="col-2">
<div class="flex justify-content-end">
<Button size="small" class="p-1 text-color" text icon="fa fa-ellipsis" @click="onClickEditComment(comment)"></Button>
</div>
</div>
</div>
</div>
</template>
<template #content>
<div class="grid">
<div class="col-12" v-if="!comment.editMode">
{{ comment.comment }}
</div>
<div class="col-12" v-else>
<MarkdownEditor v-model="comment.comment" @blur="patchComment(comment)"></MarkdownEditor>
</div>
</div>
</template>
</Card>
<CommentCard
:comment="comment.comment"
:date="comment.date_created"
:author="comment.user.username"
:editedBy="getUserEditUsername(comment)"
v-for="comment in items"
:key="comment.pk"
@comment-edited="
(editedComment) => {
patchComment(comment.pk, editedComment);
}
"
></CommentCard>
</div>

<div class="card border-noround-top" v-else>
Expand Down
40 changes: 27 additions & 13 deletions frontend/src/views/pages/projects/findings/CommentList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import FindingService from '@/service/FindingService';
import FindingTabMenu from '@/components/pages/FindingTabMenu.vue';
import BlankSlate from '@/components/BlankSlate.vue';
import FindingCommentFormDialog from '@/components/projects/findings/FindingCommentFormDialog.vue';
import CommentCard from '@/components/elements/CommentCard.vue';
export default {
name: 'FindingCommentList',
Expand Down Expand Up @@ -59,6 +60,18 @@ export default {
.finally(() => {
this.loading = false;
});
},
patchComment(pk, comment) {
let data = { comment: comment };
this.service.patchComment(this.$api, this.projectId, this.findingId, pk, data).then(() => {
this.getComments();
});
},
getUserEditUsername(comment) {
if (comment.user_edit) {
return comment.user_edit.username;
}
return comment.user_edit;
}
},
mounted() {
Expand All @@ -73,7 +86,7 @@ export default {
});
this.getComments();
},
components: { FindingCommentFormDialog, BlankSlate, FindingTabMenu }
components: { CommentCard, FindingCommentFormDialog, BlankSlate, FindingTabMenu }
};
</script>

Expand All @@ -97,18 +110,19 @@ export default {
<div class="col-12">
<FindingTabMenu class="surface-card"></FindingTabMenu>
<div class="card border-noround-top" v-if="items.length > 0">
<div class="card pb-3 pt-4" v-for="comment in items" :key="comment.pk">
<div class="grid pt-2">
<div class="col-12">
{{ comment.comment }}
</div>
</div>
<div class="grid text-color-secondary">
<div class="col-12">
<small>{{ comment.user.username }} - {{ comment.date_created }}</small>
</div>
</div>
</div>
<CommentCard
:comment="comment.comment"
:date="comment.date_created"
:editedBy="getUserEditUsername(comment)"
:author="comment.user.username"
v-for="comment in items"
:key="comment.pk"
@comment-edited="
(editedComment) => {
patchComment(comment.pk, editedComment);
}
"
></CommentCard>
</div>
<div class="card border-noround-top" v-else>
<BlankSlate title="No comments" text="No comments found!" icon="fa fa-comments"></BlankSlate>
Expand Down
3 changes: 2 additions & 1 deletion server/advisories/serializers/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

class AdvisoryCommentSerializer(serializers.ModelSerializer):
user = MinimalUserSerializer(read_only=True)
user_edit = MinimalUserSerializer(read_only=True)

class Meta:
model = AdvisoryComment
fields = ["pk", "comment", "user", "date_created", "date_updated"]
fields = ["pk", "comment", "user", "user_edit", "date_created", "date_updated"]
3 changes: 3 additions & 0 deletions server/advisories/viewsets/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ def get_queryset(self):

def perform_create(self, serializer):
serializer.save(advisory=self.request.advisory, user=self.request.user)

def perform_update(self, serializer):
serializer.save(user_edit=self.request.user)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 5.0.1 on 2024-02-04 06:41

from django.conf import settings
from django.db import migrations, models

import pecoret.core.models


class Migration(migrations.Migration):
dependencies = [
('backend', '0045_alter_user_managers'),
]

operations = [
migrations.AddField(
model_name='findingcomment',
name='user_edit',
field=models.ForeignKey(blank=True, null=True, on_delete=pecoret.core.models.CASCADE_USER_TO_GHOST,
related_name='finding_comment_edited_set', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='findingcomment',
name='user',
field=models.ForeignKey(on_delete=pecoret.core.models.CASCADE_USER_TO_GHOST, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='advisorycomment',
name='user_edit',
field=models.ForeignKey(blank=True, null=True, on_delete=pecoret.core.models.CASCADE_USER_TO_GHOST,
related_name='advisory_comment_edited_set', to=settings.AUTH_USER_MODEL),
),
]
5 changes: 4 additions & 1 deletion server/backend/models/advisory_comment.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.db import models
from pecoret.core.models import TimestampedModel

from pecoret.core.models import TimestampedModel, CASCADE_USER_TO_GHOST


class AdvisoryCommentQuerySet(models.QuerySet):
Expand All @@ -12,6 +13,8 @@ class AdvisoryComment(TimestampedModel):
advisory = models.ForeignKey('backend.Advisory', on_delete=models.CASCADE)
comment = models.TextField()
user = models.ForeignKey('backend.User', on_delete=models.SET_NULL, null=True)
user_edit = models.ForeignKey('backend.User', null=True, blank=True, on_delete=CASCADE_USER_TO_GHOST,
related_name='advisory_comment_edited_set')

def __str__(self):
return str(self.advisory)
Expand Down
7 changes: 4 additions & 3 deletions server/backend/models/finding_comment.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.db import models
from pecoret.core.models import TimestampedModel
from pecoret.core.models import TimestampedModel, CASCADE_USER_TO_GHOST


class FindingCommentQuerySet(models.QuerySet):
Expand All @@ -11,11 +11,12 @@ def for_project(self, project):


class FindingComment(TimestampedModel):
# TODO: CASCADE to set to a "Ghost" user as github does
objects = FindingCommentQuerySet.as_manager()
user = models.ForeignKey('backend.User', on_delete=models.PROTECT)
user = models.ForeignKey('backend.User', on_delete=CASCADE_USER_TO_GHOST)
comment = models.TextField()
finding = models.ForeignKey('backend.Finding', on_delete=models.CASCADE)
user_edit = models.ForeignKey('backend.User', null=True, blank=True, on_delete=CASCADE_USER_TO_GHOST,
related_name='finding_comment_edited_set')

class Meta:
ordering = ["date_created"]
3 changes: 2 additions & 1 deletion server/backend/serializers/finding_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

class FindingCommentSerializer(serializers.ModelSerializer):
user = MinimalUserSerializer(read_only=True)
user_edit = MinimalUserSerializer(read_only=True)

class Meta:
model = FindingComment
fields = ["pk", "date_created", "date_updated", "user", "comment"]
fields = ["pk", "date_created", "date_updated", "user", "comment", "user_edit"]
3 changes: 3 additions & 0 deletions server/backend/viewsets/finding_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ def get_queryset(self):

def perform_create(self, serializer):
serializer.save(user=self.request.user, finding=self.request.finding)

def perform_update(self, serializer):
serializer.save(user_edit=self.request.user)

0 comments on commit c73d605

Please sign in to comment.