set book tags on book create step

This commit is contained in:
SvyatoslavArtymovych 2023-05-16 13:27:19 +03:00
parent 71126511ce
commit 063594c7f9
9 changed files with 114 additions and 30 deletions

View File

@ -9,6 +9,7 @@ from app.logger import log
class BaseBookForm(FlaskForm):
label = StringField("Label", [DataRequired(), Length(6, 256)])
about = StringField("About")
tags = StringField("Tags")
class CreateBookForm(BaseBookForm):
@ -17,7 +18,6 @@ class CreateBookForm(BaseBookForm):
class EditBookForm(BaseBookForm):
book_id = StringField("User ID", [DataRequired()])
tags = StringField("Tags")
submit = SubmitField("Edit book")
def validate_label(self, field):

File diff suppressed because one or more lines are too long

View File

@ -76,8 +76,6 @@
{% block right_sidebar %} {% include 'right_sidebar.html' %} {% endblock %}
{% include 'book/add_book_modal.html' %}
<!-- prettier-ignore -->
<script src="{{ url_for('static', filename='js/main.js') }}" type="text/javascript" defer></script>

View File

@ -3,7 +3,7 @@
<div id="add-book-modal" tabindex="-1" aria-hidden="true" class="fixed top-0 left-0 right-0 z-50 hidden w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative w-full max-w-2xl max-h-full">
<!-- Modal content -->
<form action="{{ url_for('book.create') }}" method="post" class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<form action="{{ url_for('book.create') }}" method="post" class="prevent-submit-on-enter relative bg-white rounded-lg shadow dark:bg-gray-700">
{{ form_hidden_tag() }}
<input type="hidden" name="user_id" id="user-edit-id" value="0" />
<input type="hidden" name="next_url" id="user-edit-next_url" value="" />
@ -14,10 +14,23 @@
</div>
<!-- Modal body -->
<div class="p-6 space-y-6">
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<label for="label" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white" >Label</label >
<input type="text" name="label" id="label" class="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-600 focus:border-blue-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Name" required />
<div class="col-span-6 sm:col-span-3">
<label for="label" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white" >Label</label >
<input type="text" name="label" id="label" class="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-600 focus:border-blue-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Name" required />
</div>
<div class="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 shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-600 focus:border-blue-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 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>

View File

@ -3,6 +3,11 @@
{% set selected_tab='my_library' %}
{% block content %}
{% if current_user.is_authenticated %}
{% include 'book/add_book_modal.html' %}
{% endif %}
<div
class="md:mr-64 relative overflow-x-auto shadow-md sm:rounded-lg mt-1 h-box w-box flex">
{% if not current_user.is_authenticated %}

View File

@ -36,7 +36,7 @@
<div id="myTabContent">
<!-- prettier-ignore -->
<div class="hidden pl-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="settings" role="tabpanel" aria-labelledby="settings-tab">
<form action="{{ url_for('book.edit', book_id=book.id) }}" method="post" class="settings-form mb-0 flex flex-col space-y-2 w-1/2">
<form action="{{ url_for('book.edit', book_id=book.id) }}" method="post" class="prevent-submit-on-enter settings-form mb-0 flex flex-col space-y-2 w-1/2">
{{ form_hidden_tag() }}
<input value="{{book.id}}" type="text" name="book_id" id="book_id" class="hidden" placeholder="Book id" required>
<div>
@ -61,6 +61,7 @@
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">
{% for tag in book.tags %}

View File

@ -81,6 +81,10 @@ def create():
label="Root Collection", version_id=version.id, is_root=True
).save()
tags = form.tags.data
if tags:
set_book_tags(book, tags)
flash("Book added!", "success")
return redirect(url_for("book.my_library"))
else:

View File

@ -1,4 +1,8 @@
const handleClickOnTag = (element: Element, addedWords: string[]) => {
const handleClickOnTag = (
element: Element,
addedWords: string[],
tagsToSubmitInput: HTMLInputElement,
) => {
const tag = element.innerHTML;
addedWords = addedWords.filter(el => el != tag);
@ -8,23 +12,37 @@ const handleClickOnTag = (element: Element, addedWords: string[]) => {
multipleInput.value = tag;
// prettier-ignore
const tagsToSubmitInput: HTMLInputElement = document.querySelector('.tags-to-submit');
tagsToSubmitInput.value = addedWords.join();
return addedWords;
};
export function initMultipleInput() {
const settingsForm = document.querySelector('.settings-form');
settingsForm.addEventListener('keypress', (e: any) => {
const multipleInputJs = () => {
const form = document.querySelector('.prevent-submit-on-enter');
if (!form) {
return;
}
form.addEventListener('keypress', (e: any) => {
if (e.keyCode === 13) {
e.preventDefault();
}
});
// prettier-ignore
const tagsToSubmitInput: HTMLInputElement = document.querySelector('.tags-to-submit');
const multipleInput: any = document.querySelector('.multiple-input');
const tagsToSubmitInputClassName = multipleInput.getAttribute(
'data-save-results-to',
);
if (!tagsToSubmitInputClassName) {
console.error(
'Please set data-save-results-to attribute to .multiple-input element',
);
return;
}
const tagsToSubmitInput: HTMLInputElement = document.querySelector(
'.' + tagsToSubmitInputClassName,
);
const wordsBlock: HTMLDivElement = document.querySelector(
'.multiple-input-items',
@ -34,7 +52,7 @@ export function initMultipleInput() {
wordDivs.forEach(el => {
addedWords.push(el.innerHTML);
el.addEventListener('click', () => {
addedWords = handleClickOnTag(el, addedWords);
addedWords = handleClickOnTag(el, addedWords, tagsToSubmitInput);
});
});
@ -81,7 +99,7 @@ export function initMultipleInput() {
wordDiv.innerHTML = inputValue;
addedWords.push(inputValue);
wordDiv.addEventListener('click', () => {
addedWords = handleClickOnTag(wordDiv, addedWords);
addedWords = handleClickOnTag(wordDiv, addedWords, tagsToSubmitInput);
});
wordsBlock.appendChild(wordDiv);
@ -108,4 +126,10 @@ export function initMultipleInput() {
// }
// }
});
};
export function initMultipleInput() {
document.addEventListener('DOMContentLoaded', () => {
multipleInputJs();
});
}

View File

@ -1,9 +1,36 @@
# flake8: noqa F501
from flask import current_app as Response
from flask.testing import FlaskClient, FlaskCliRunner
from flask.testing import FlaskClient
from app import models as m, db
from tests.utils import login, logout
from app import models as m
from tests.utils import login
def test_create_tags_on_book_create(client: FlaskClient):
login(client)
BOOK_NAME = "Test Book"
tags = "tag1,tag2,tag3"
response: Response = client.post(
"/book/create",
data=dict(label=BOOK_NAME, tags=tags),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Book added!" in response.data
book = m.Book.query.filter_by(label=BOOK_NAME).first()
assert book.tags
splitted_tags = [tag.title() for tag in tags.split(",")]
assert len(book.tags) == 3
for tag in book.tags:
tag: m.Tag
assert tag.name in splitted_tags
tags_from_db: m.Tag = m.Tag.query.all()
assert len(tags_from_db) == 3
def test_create_tags_on_book_edit(client: FlaskClient):