tagging sub comments

This commit is contained in:
SvyatoslavArtymovych 2023-05-17 18:01:39 +03:00
parent 0666a29de6
commit 4b8ff4ba40
7 changed files with 102 additions and 61 deletions

View File

@ -5,11 +5,11 @@ from wtforms.validators import DataRequired, Length
class BaseCommentForm(FlaskForm):
text = StringField("Text", [DataRequired(), Length(3, 256)])
tags = StringField("Tags")
class CreateCommentForm(BaseCommentForm):
parent_id = StringField("Text")
tags = StringField("Tags")
submit = SubmitField("Create")

View File

@ -1157,14 +1157,14 @@ input:checked + .toggle-bg {
z-index: 100;
}
.z-\[55\] {
z-index: 55;
}
.z-\[150\] {
z-index: 150;
}
.z-\[55\] {
z-index: 55;
}
.col-span-6 {
grid-column: span 6 / span 6;
}
@ -1409,6 +1409,10 @@ input:checked + .toggle-bg {
height: 1rem;
}
.h-40 {
height: 10rem;
}
.h-5 {
height: 1.25rem;
}
@ -1454,14 +1458,6 @@ input:checked + .toggle-bg {
height: 100vh;
}
.h-40 {
height: 10rem;
}
.h-\[calc\(100\%\)\] {
height: calc(100%);
}
.max-h-full {
max-height: 100%;
}
@ -1724,6 +1720,10 @@ input:checked + .toggle-bg {
justify-content: space-between;
}
.gap-1 {
gap: 0.25rem;
}
.gap-2 {
gap: 0.5rem;
}
@ -1732,10 +1732,6 @@ input:checked + .toggle-bg {
gap: 1.5rem;
}
.gap-1 {
gap: 0.25rem;
}
.-space-x-px > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(-1px * var(--tw-space-x-reverse));
@ -2046,6 +2042,11 @@ input:checked + .toggle-bg {
background-color: rgb(200 30 30 / var(--tw-bg-opacity));
}
.bg-sky-300 {
--tw-bg-opacity: 1;
background-color: rgb(125 211 252 / var(--tw-bg-opacity));
}
.bg-slate-300 {
--tw-bg-opacity: 1;
background-color: rgb(203 213 225 / var(--tw-bg-opacity));
@ -2074,16 +2075,6 @@ input:checked + .toggle-bg {
background-color: rgb(255 255 255 / 0.5);
}
.bg-sky-300 {
--tw-bg-opacity: 1;
background-color: rgb(125 211 252 / var(--tw-bg-opacity));
}
.bg-black {
--tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
.bg-opacity-50 {
--tw-bg-opacity: 0.5;
}
@ -2537,16 +2528,16 @@ input:checked + .toggle-bg {
background-color: rgb(155 28 28 / var(--tw-bg-opacity));
}
.hover\:bg-white:hover {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.hover\:bg-sky-400:hover {
--tw-bg-opacity: 1;
background-color: rgb(56 189 248 / var(--tw-bg-opacity));
}
.hover\:bg-white:hover {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.hover\:bg-gradient-to-bl:hover {
background-image: linear-gradient(to bottom left, var(--tw-gradient-stops));
}

View File

@ -213,12 +213,38 @@
>
{{ form_hidden_tag() }}
<input type="hidden" name="parent_id" id="parent_id" value="{{comment.id}}" />
<div class="relative z-0 w-full mb-6 group">
<!-- prettier-ignore -->
<input autocomplete="off" maxlength="256" type="text" name="text" id="floating_email" class="block py-2.5 px-0 w-full text-sm text-gray-900 bg-transparent border-0 border-b-2 border-gray-300 appearance-none dark:text-white dark:border-gray-600 dark:focus:border-blue-500 focus:outline-none focus:ring-0 focus:border-blue-600 peer" placeholder=" " required />
<!-- prettier-ignore -->
<label for="floating_email" class="peer-focus:font-medium absolute text-sm text-gray-500 dark:text-gray-400 duration-300 transform -translate-y-6 scale-75 top-3 -z-10 origin-[0] peer-focus:left-0 peer-focus:text-blue-600 peer-focus:dark:text-blue-500 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-6" >Comment</label >
</div>
<div class="relative z-0 w-full group">
<div class="mb-2">
<label for="tags-input" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Comment
</label>
<input
name="text"
autocomplete="off"
maxlength="256"
type="text"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="Leave your comment here"
required
>
</div>
<div class="multiple-input-block mb-6">
<label for="tags-input" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Tags
</label>
<input type="text" name="tags" class="hidden tags-to-submit">
<input
type="text"
id="tags-input"
class="multiple-input mb-3 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="e.g. Law (press 'Enter' or Comma to add tag. Click on tag to edit it)"
data-save-results-to="tags-to-submit"
>
<div class="multiple-input-items gap-1 flex flex-wrap">
</div>
</div>
</div>
<!-- prettier-ignore -->
<button type="submit" class="ml-auto text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"> Leave comment </button>
</form>

View File

@ -1013,7 +1013,6 @@ def qa_view(
sub_collection=sub_collection if sub_collection_id else None,
section=section,
interpretation=interpretation,
breadcrumbs=breadcrumbs,
)
@ -1079,7 +1078,6 @@ def create_comment(
sub_collection_id=sub_collection_id,
section_id=section_id,
interpretation_id=interpretation_id,
breadcrumbs=breadcrumbs,
)
section: m.Section = db.session.get(m.Section, section_id)
if not section or section.is_deleted:
@ -1119,7 +1117,7 @@ def create_comment(
set_comment_tags(comment, tags)
flash("Success!", "success")
return redirect(request.referrer)
return redirect(redirect_url)
else:
log(log.ERROR, "Comment create errors: [%s]", form.errors)
for field, errors in form.errors.items():
@ -1127,7 +1125,7 @@ def create_comment(
for error in errors:
flash(error.lower().replace("field", field_label).title(), "danger")
return redirect(request.referrer)
return redirect(redirect_url)
@bp.route(
@ -1200,13 +1198,18 @@ def comment_edit(
sub_collection_id: int | None = None,
):
form = f.EditCommentForm()
comment_id = form.comment_id.data
comment: m.Comment = db.session.get(m.Comment, comment_id)
if form.validate_on_submit():
comment_id = form.comment_id.data
comment: m.Comment = db.session.get(m.Comment, comment_id)
comment.text = form.text.data
comment.edited = True
log(log.INFO, "Delete comment [%s]", comment)
log(log.INFO, "Edit comment [%s]", comment)
tags = form.tags.data
if tags:
set_comment_tags(comment, tags)
comment.save()
flash("Success!", "success")

View File

@ -23,11 +23,11 @@ def get_all():
m.Collection.id == m.Section.collection_id,
m.BookVersion.id == m.Section.version_id,
m.Book.id == m.BookVersion.book_id,
m.Book.is_deleted.is_(False),
m.BookVersion.is_deleted.is_(False),
m.Interpretation.is_deleted.is_(False),
m.Section.is_deleted.is_(False),
m.Collection.is_deleted.is_(False),
m.Book.is_deleted == False, # noqa: E712
m.BookVersion.is_deleted == False, # noqa: E712
m.Interpretation.is_deleted == False, # noqa: E712
m.Section.is_deleted == False, # noqa: E712
m.Collection.is_deleted == False, # noqa: E712
)
)
.order_by(m.Interpretation.created_at.desc())

View File

@ -1,5 +1,5 @@
# flake8: noqa F501
from flask import current_app as Response
from flask import current_app as Response, url_for
from flask.testing import FlaskClient, FlaskCliRunner
from app import models as m, db

View File

@ -1,7 +1,7 @@
from flask import current_app as Response
from flask.testing import FlaskClient
from app import models as m
from app import models as m, db
from tests.utils import login, create_test_book
@ -37,7 +37,7 @@ def test_create_tags_on_book_edit(client: FlaskClient):
_, user = login(client)
book: m.Book = m.Book(label="Test book", user_id=user.id).save()
m.BookVersion = m.BookVersion(semver="1.0.0", book_id=book.id).save()
m.BookVersion(semver="1.0.0", book_id=book.id).save()
assert not book.tags
@ -87,14 +87,14 @@ def test_create_tags_on_book_edit(client: FlaskClient):
assert len(book.tags) == 0
def test_create_tags_on_comment_create(client: FlaskClient):
def test_create_tags_on_comment_create_and_edit(client: FlaskClient):
_, user = login(client)
create_test_book(user.id, 1)
book = m.Book.query.get(1)
collection = m.Collection.query.get(1)
section = m.Section.query.get(1)
interpretation = m.Interpretation.query.get(1)
book = db.session.get(m.Book, 1)
collection = db.session.get(m.Collection, 1)
section = db.session.get(m.Section, 1)
interpretation = db.session.get(m.Interpretation, 1)
tags = "tag1,tag2,tag3"
response: Response = client.post(
@ -122,14 +122,35 @@ def test_create_tags_on_comment_create(client: FlaskClient):
tags_from_db: m.Tag = m.Tag.query.all()
assert len(tags_from_db) == 3
tags = "tag1,tag5,tag7"
response: Response = client.post(
f"/book/{book.id}/{collection.id}/{section.id}/{interpretation.id}/comment_edit",
data=dict(text=comment.text, tags=tags, comment_id=comment.id),
follow_redirects=True,
)
assert response.status_code == 200
comment: m.Comment = m.Comment.query.filter_by(text="some text").first()
assert comment
assert comment.tags
splitted_tags = [tag.title() for tag in tags.split(",")]
assert len(comment.tags) == 3
for tag in comment.tags:
tag: m.Tag
assert tag.name in splitted_tags
tags_from_db: m.Tag = m.Tag.query.all()
assert len(tags_from_db) == 5
def test_create_tags_on_interpretation_create_and_edit(client: FlaskClient):
_, user = login(client)
create_test_book(user.id, 1)
book = m.Book.query.get(1)
collection = m.Collection.query.get(1)
section = m.Section.query.get(1)
book = db.session.get(m.Book, 1)
collection = db.session.get(m.Collection, 1)
section = db.session.get(m.Section, 1)
tags = "tag1,tag2,tag3"
label_1 = "Test Interpretation #1 Label"