Merge pull request #90 from Simple2B/kostia/feat/multiple_sub_collection

Kostia/feat/multiple sub collection
This commit is contained in:
Костя Столярский 2023-05-30 15:59:41 +03:00 committed by GitHub
commit bfd7d8fb71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 504 additions and 3547 deletions

View File

@ -72,11 +72,13 @@ def create_app(environment="development"):
form_hidden_tag,
display_tags,
build_qa_url_using_interpretation,
recursive_render,
)
app.jinja_env.globals["form_hidden_tag"] = form_hidden_tag
app.jinja_env.globals["display_tags"] = display_tags
app.jinja_env.globals["build_qa_url"] = build_qa_url_using_interpretation
app.jinja_env.globals["recursive_render"] = recursive_render
# Error handlers.
@app.errorhandler(HTTPException)

View File

@ -2,7 +2,7 @@ import re
from flask import current_app
from flask_wtf import FlaskForm
from flask import url_for
from flask import url_for, render_template
from app import models as m
@ -49,3 +49,11 @@ def build_qa_url_using_interpretation(interpretation: m.Interpretation):
interpretation_id=interpretation.id,
)
return url
def recursive_render(template: str, collection: m.Collection, book: m.Book):
return render_template(
template,
collection=collection,
book=book,
)

File diff suppressed because one or more lines are too long

View File

@ -42,24 +42,23 @@
</div>
<!-- prettier-ignore -->
{% for collection in book.versions[-1].children_collections if not collection.is_root and not collection.is_deleted %}
{% set outer_loop = loop %}
<div>
<div class="flex items-center justify-start w-full font-medium text-left text-gray-500 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800 dark:text-gray-400">
<button class="bg-inherit" type="button" data-accordion-target="#accordion-collapse-body-{{loop.index}}" aria-expanded="true" aria-controls="accordion-collapse-body-{{loop.index}}">
<button class="bg-inherit" type="button" data-accordion-target="#accordion-collapse-body-{{collection.id}}" aria-expanded="true" aria-controls="accordion-collapse-body-{{collection.id}}">
<!-- prettier-ignore -->
<svg data-accordion-icon class="w-6 h-6 rotate-180 shrink-0" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path> </svg>
</button>
<a id="accordion-collapse-heading-{{loop.index}}" class=" text-black dark:text-white ">
<form id="rename-collection-label-form-{{loop.index}}" data-book-id='{{book.id}}' data-collection-id="{{collection.id}}" method="post" class="mb-0">
<a id="accordion-collapse-heading-{{collection.id}}" class=" text-black dark:text-white ">
<form id="rename-collection-label-form-{{collection.id}}" data-book-id='{{book.id}}' data-collection-id="{{collection.id}}" method="post" class="mb-0">
{{ form_hidden_tag() }}
<input class=" bg-inherit border-none " value="{{collection.label}}" type="text" name="label" id="edit-collection-label-{{loop.index}}" placeholder="Collection label" required readonly/>
<input class=" bg-inherit border-none " value="{{collection.label}}" type="text" name="label" id="edit-collection-label-{{collection.id}}" placeholder="Collection label" required readonly/>
<button name="submit" type="submit"></button>
</form>
</a>
</div>
<svg id="dropdownCollectionContextButton{{loop.index}}" data-dropdown-toggle="dropdown" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 0 0" stroke-width="1.5" stroke="none" class="w-0 h-0"></svg>
<svg id="dropdownCollectionContextButton{{collection.id}}" data-dropdown-toggle="dropdown" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 0 0" stroke-width="1.5" stroke="none" class="w-0 h-0"></svg>
</div>
<div data="collection-context-menu-{{loop.index}}" id="dropdown" class="z-10 hidden bg-white divide-y divide-gray-800 border border-gray-800 dark:border-none dark:divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
<div data="collection-context-menu-{{collection.id}}" id="dropdown" class="z-10 hidden bg-white divide-y divide-gray-800 border border-gray-800 dark:border-none dark:divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
{% if current_user.is_authenticated %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
@ -78,7 +77,7 @@
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" id="rename-collection-button-{{loop.index}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Rename Collection</button>
<button type="button" id="rename-collection-button-{{collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Rename Collection</button>
</li>
<li>
<button type="button" id="callDeleteCollectionModal" data-modal-target="delete-collection-modal" data-modal-toggle="delete-collection-modal" data-collection-id="{{collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Delete Collection</button>
@ -98,144 +97,8 @@
{% endif %}
</div>
<!-- prettier-ignore -->
<div id="accordion-collapse-body-{{loop.index}}" class="hidden" aria-labelledby="accordion-collapse-heading-{{loop.index}}">
<div class="ml-6">
{% if not collection.is_leaf %}
<!-- if collection has sub_collection make for loop for it -->
<!-- Nested accordion -->
{% for sub_collection in collection.children if not sub_collection.is_deleted%}
<div id="accordion-nested-collapse" data-accordion="open">
<div class="flex items-center justify-start w-full font-medium text-left text-gray-500 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800 dark:text-gray-400">
<button
class="bg-inherit"
type="button"
data-accordion-target="#accordion-nested-collapse-body-{{outer_loop.index}}-{{loop.index}}"
aria-expanded="true"
aria-controls="accordion-nested-collapse-body-{{outer_loop.index}}-{{loop.index}}">
<!-- prettier-ignore -->
<svg data-accordion-icon class="w-6 h-6 shrink-0" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path> </svg>
</button>
<a id="accordion-nested-collapse-heading-{{outer_loop.index}}-{{loop.index}}" class=" text-black dark:text-white ">
<form id="rename-sub-collection-label-form-{{loop.index}}" data-book-id='{{book.id}}' data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" method="post" class="mb-0">
{{ form_hidden_tag() }}
<input class=" bg-inherit border-none " value="{{sub_collection.label}}" type="text" name="label" id="edit-sub-collection-label-{{loop.index}}" placeholder="Sub collection label" required readonly/>
<button name="submit" type="submit"></button>
</form>
</a>
</div>
<svg id="dropdownSubCollectionContextButton{{loop.index}}" data-dropdown-toggle="dropdown" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 0 0" stroke-width="1.5" stroke="none" class="w-0 h-0"></svg>
<div data="sub-collection-context-menu-{{loop.index}}" id="dropdown" class="z-10 hidden bg-white divide-y divide-gray-800 border border-gray-800 dark:border-none dark:divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
{% if current_user.is_authenticated %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" id="callAddSectionModal" data-modal-target="add-section-modal" data-modal-toggle="add-section-modal" data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">New Section</button>
</li>
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" id="rename-sub-collection-button-{{loop.index}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Rename Sub Collection</button>
</li>
<li>
<button type="button" id="callDeleteSubCollectionModal" data-modal-target="delete-sub-collection-modal" data-modal-toggle="delete-sub-collection-modal" data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Delete Sub Collection</button>
</li>
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Export Sub Collection</button>
</li>
</ul>
{% else %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Connect your wallet to do this</button>
</li>
</ul>
{% endif %}
</div>
<!-- prettier-ignore -->
<div id="accordion-nested-collapse-body-{{outer_loop.index}}-{{loop.index}}" class="hidden" aria-labelledby="accordion-nested-collapse-heading-{{loop.index}}">
<div class="ml-6">
<!-- here comes for loop for all section in this sub_collection-->
{% for section in sub_collection.active_sections %}
<div class="">
<button type="button" href="#section-{{section.label}}" id="section-heading-{{loop.index}}" class="text-gray-500 dark:text-gray-400">
<form id="rename-section-label-form-{{loop.index}}" data-book-id='{{book.id}}' data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" data-section-id="{{section.id}}" method="post">
{{ form_hidden_tag() }}
<input class=" bg-inherit border-none underline" value="{{section.label}}" type="text" name="label" id="edit-section-label-{{loop.index}}" placeholder="Section label" required readonly/>
<button name="submit" type="submit"></button>
</form>
</button>
<svg id="dropdownSectionContextButton{{loop.index}}" data-dropdown-toggle="dropdown" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 0 0" stroke-width="1.5" stroke="none" class="w-0 h-0"></svg>
<div data="section-context-menu-{{loop.index}}" id="dropdown" class="z-10 hidden bg-white divide-y divide-gray-800 border border-gray-800 dark:border-none dark:divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
{% if current_user.is_authenticated %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" id="rename-section-button-{{loop.index}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Rename Section</button>
</li>
<li>
<button type="button" data-modal-target="delete-section-modal" data-modal-toggle="delete-section-modal" id="callDeleteSectionModal" data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" data-section-id="{{section.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Delete Section</button>
</li>
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Export Section</button>
</li>
</ul>
{% else %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Connect your wallet to do this</button>
</li>
</ul>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
<!-- End: Nested accordion -->
{% else %}
<!-- if collection doesn't have sub_collection -->
<div class="ml-6">
<!-- here comes for loop for all section in this collection-->
{% for section in collection.active_sections %}
<button type="button" href="#section-{{section.label}}" id="section-heading-{{loop.index}}" class="text-gray-500 dark:text-gray-400">
<form id="rename-section-label-form-{{loop.index}}" data-book-id='{{book.id}}' data-collection-id="{{collection.id}}" data-sub-collection-id="_" data-section-id="{{section.id}}" method="post">
{{ form_hidden_tag() }}
<input class=" bg-inherit border-none underline" value="{{section.label}}" type="text" name="label" id="edit-section-label-{{loop.index}}" placeholder="Section label" required readonly/>
<button name="submit" type="submit"></button>
</form>
</button>
<svg id="dropdownSectionContextButton{{loop.index}}" data-dropdown-toggle="dropdown" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 0 0" stroke-width="1.5" stroke="none" class="w-0 h-0"></svg>
<div data="section-context-menu-{{loop.index}}" id="dropdown" class="z-10 hidden bg-white divide-y divide-gray-800 border border-gray-800 dark:border-none dark:divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
{% if current_user.is_authenticated %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" id="rename-section-button-{{loop.index}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Rename Section</button>
</li>
<li>
<button type="button" data-modal-target="delete-collection-modal" data-modal-toggle="delete-collection-modal" id="callDeleteSectionModal" data-collection-id="{{collection.id}}" data-sub-collection-id="_" data-section-id="{{section.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Delete Section</button>
</li>
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Export Section</button>
</li>
</ul>
{% else %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">Connect your wallet to do this</button>
</li>
</ul>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
</div>
<div id="accordion-collapse-body-{{collection.id}}" class="hidden" aria-labelledby="accordion-collapse-heading-{{collection.id}}">
{{recursive_render("book/components/sub_collection_tab_content.html",collection,book)|safe}}
</div>
{% endfor %}
</div>
@ -274,127 +137,7 @@
{% if not collection.is_leaf and not collection.children %}
<p class="ml-3 my-3 italic text-sm">Collection is empty</p>
{% endif %}
{% if not collection.is_leaf %}
<!-- if collection has sub_collection make for loop for it -->
{% for sub_collection in collection.children if not sub_collection.is_deleted%}
<p class="my-3">##{{sub_collection.label}}</p>
{% if not sub_collection.active_sections %}
<p class="ml-3 my-3 italic text-sm">This sub collection is empty</p>
{% endif %}
{% for section in sub_collection.active_sections %}
<div class="bg-inherit max-w-full text-gray-900 dark:text-white mt-1">
<div class="flex flex-col pb-3 w-full">
<div class="flex w-full mb-1 dark:text-gray-100 flex-col">
<!-- prettier-ignore -->
<a href="{{url_for('book.interpretation_view', book_id=book.id, section_id=section.id)}}">
<p id="section-{{section.label}}" class="truncate my-3">{{ section.label }}</p></a>
{% if not section.active_interpretations %}
<p class="ml-3 my-3 italic text-sm">This section is empty</p>
{% else %}
<div class="ql-snow truncate md:max-w-xl">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{display_tags(section.approved_interpretation.text)|safe }}</p>
</div>
</div>
<div class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm">Interpretation by <a href="{{url_for('user.profile',user_id=section.approved_interpretation.user.id)}}" class=" text-blue-500 {% if section.approved_interpretation.user.is_deleted %}line-through{% endif %}">{{section.approved_interpretation.user.username}}</a> on {{section.approved_interpretation.created_at.strftime('%B %d, %Y')}}</span>
<button data-tooltip-target="tooltip-click" data-tooltip-trigger="click" id="copyLinkButton" type="button" class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white" data-link="{{ build_qa_url(section.approved_interpretation) }}"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg> </button>
<div id="tooltip-click" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"> Link copied! <div class="tooltip-arrow" data-popper-arrow></div> </div>
</div>
<!--Comments-->
{% if not section.approved_comments %}
<p>No comments for current section</p>
{% else %}
<div id="accordion-comments-collapse-{{loop.index}}" data-accordion="collapse">
<h2 id="accordion-comments-collapse-{{loop.index}}-heading-{{loop.index}}">
<button type="button" class="flex items-center bg-inherit justify-start w-full p-5 font-medium text-left" data-accordion-target="#accordion-comments-collapse-{{loop.index}}-body-{{loop.index}}" aria-expanded="false" aria-controls="accordion-collapse-body-1">
<svg data-accordion-icon class="w-6 h-6 rotate-180 shrink-0" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
<span><i>Comments:</i></span>
</button>
</h2>
<div id="accordion-comments-collapse-{{loop.index}}-body-{{loop.index}}" class="hidden" aria-labelledby="accordion-collapse-heading-{{loop.index}}">
{% for comment in section.approved_comments %}
<div class="p-5 ml-6">
<div class="dark:text-white h-30">
<div class="ql-snow mb-2 truncate md:max-w-xl">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{ display_tags(comment.text)|safe }}</p>
</div>
</div>
</div>
<div class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm">Created by <a href="{{url_for('user.profile',user_id=comment.user.id)}}" class=" text-blue-500 {% if comment.user.is_deleted %}line-through{% endif %}">{{comment.user.username}}</a> on {{comment.created_at.strftime('%B %d, %Y')}}</span>
<button data-tooltip-target="tooltip-click" data-tooltip-trigger="click" id="copyLinkButton" type="button" class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white" data-link="{{ build_qa_url(section.approved_interpretation) }}">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>
</button>
<div id="tooltip-click" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"> Link copied! <div class="tooltip-arrow" data-popper-arrow></div> </div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
{% endfor %}
{% else %}
{% for section in collection.active_sections %}
<a href="{{url_for('book.interpretation_view', book_id=book.id, section_id=section.id)}}">
<p id="section-{{section.label}}" class="truncate my-3">{{ section.label }}</p></a>
{% if not section.active_interpretations %}
<p class="ml-3 my-3 italic text-sm">This section is empty</p>
{% else %}
<div class="ql-snow truncate md:max-w-xl mb-3">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{ display_tags(section.approved_interpretation.text)|safe }}</p>
</div>
</div>
<div class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm">Interpretation by <a href="{{url_for('user.profile',user_id=section.approved_interpretation.user.id)}}" class=" text-blue-500 {% if section.approved_interpretation.user.is_deleted %}line-through{% endif %}">{{section.approved_interpretation.user.username}}</a> on {{section.approved_interpretation.created_at.strftime('%B %d, %Y')}}</span>
<button data-tooltip-target="tooltip-click" data-tooltip-trigger="click" id="copyLinkButton" type="button" class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white" data-link="{{ build_qa_url(section.approved_interpretation) }}"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg> </button>
<div id="tooltip-click" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"> Link copied! <div class="tooltip-arrow" data-popper-arrow></div> </div>
</div>
<!--Comments-->
{% if not section.approved_comments %}
<div class="mb-3">
<p>No comments for current section</p>
</div>
{% else %}
<div id="accordion-comments-collapse-nest{{loop.inde}}" data-accordion="collapse" class="mb-3">
<h2 id="accordion-comments-collapse-nest{{loop.inde}}-heading-{{loop.index}}">
<button type="button" class="flex items-center bg-inherit justify-start w-full p-5 font-medium text-left" data-accordion-target="#accordion-comments-collapse-nest{{loop.inde}}-body-{{loop.index}}" aria-expanded="false" aria-controls="accordion-collapse-body-1">
<svg data-accordion-icon class="w-6 h-6 rotate-180 shrink-0" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
<span><i>Comments:</i></span>
</button>
</h2>
<div id="accordion-comments-collapse-nest{{loop.inde}}-body-{{loop.index}}" class="hidden" aria-labelledby="accordion-collapse-heading-1">
{% for comment in section.approved_comments %}
<div class="p-5 ml-6">
<div class="dark:text-white h-30">
<div class="ql-snow mb-2 truncate md:max-w-xl">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{ display_tags(comment.text)|safe }}</p>
</div>
</div>
</div>
<div class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm">Created by <a href="{{url_for('user.profile',user_id=comment.user.id)}}" class=" text-blue-500 {% if comment.user.is_deleted %}line-through{% endif %}">{{comment.user.username}}</a> on {{comment.created_at.strftime('%B %d, %Y')}}</span>
<button data-tooltip-target="tooltip-click" data-tooltip-trigger="click" id="copyLinkButton" type="button" class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white" data-link="{{ build_qa_url(section.approved_interpretation) }}">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" /> </svg>
</button>
<div id="tooltip-click" role="tooltip" class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"> Link copied! <div class="tooltip-arrow" data-popper-arrow></div> </div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{{recursive_render("book/components/sub_collection_preview_content.html",collection,book)|safe}}
{% endfor %}
</div>
<!-- prettier-ignore -->

View File

@ -0,0 +1,91 @@
<div class="">
<button
type="button"
href="#section-{{section.label}}"
id="section-heading-{{section.id}}"
class="text-gray-500 dark:text-gray-400">
<!-- prettier-ignore -->
<form
id="rename-section-label-form-{{section.id}}"
data-book-id="{{book.id}}"
data-collection-id="{{collection.id}}"
{% if sub_collection %}
data-sub-collection-id="{{sub_collection.id}}"
{% endif %}
data-section-id="{{section.id}}"
method="post">
{{ form_hidden_tag() }}
<input
class="bg-inherit border-none underline"
value="{{section.label}}"
type="text"
name="label"
id="edit-section-label-{{section.id}}"
placeholder="Section label"
required
readonly />
<button name="submit" type="submit"></button>
</form>
</button>
<svg
id="dropdownSectionContextButton{{section.id}}"
data-dropdown-toggle="dropdown"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 0 0"
stroke-width="1.5"
stroke="none"
class="w-0 h-0"></svg>
<div
data="section-context-menu-{{section.id}}"
id="dropdown"
class="z-10 hidden bg-white divide-y divide-gray-800 border border-gray-800 dark:border-none dark:divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
{% if current_user.is_authenticated %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button
type="button"
id="rename-section-button-{{section.id}}"
class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">
Rename Section
</button>
</li>
<li>
<!-- prettier-ignore -->
<button
type="button"
data-modal-target="delete-section-modal"
data-modal-toggle="delete-section-modal"
id="callDeleteSectionModal"
data-collection-id="{{collection.id}}"
{% if sub_collection %}
data-sub-collection-id="{{sub_collection.id}}"
{% endif %}
data-section-id="{{section.id}}"
class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">
Delete Section
</button>
</li>
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button
type="button"
class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">
Export Section
</button>
</li>
</ul>
{% else %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button
type="button"
class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">
Connect your wallet to do this
</button>
</li>
</ul>
{% endif %}
</div>
</div>

View File

@ -0,0 +1,304 @@
{% if not collection.is_leaf %}
<!-- if collection has sub_collection make for loop for it -->
{% for sub_collection in collection.children if not sub_collection.is_deleted%}
<p class="my-3">##{{sub_collection.label}}</p>
{% if not sub_collection.active_sections and not sub_collection.children %}
<p class="ml-3 my-3 italic text-sm">This sub collection is empty</p>
{% endif %}
<!-- prettier-ignore -->
{% if sub_collection.children %}
{{recursive_render("book/components/sub_collection_preview_content.html",sub_collection,book)|safe}}
{% else %}
<!-- prettier-ignore -->
{% for section in sub_collection.active_sections %}
<div class="bg-inherit max-w-full text-gray-900 dark:text-white mt-1">
<div class="flex flex-col pb-3 w-full">
<div class="flex w-full mb-1 dark:text-gray-100 flex-col">
<!-- prettier-ignore -->
<a href="{{url_for('book.interpretation_view', book_id=book.id, section_id=section.id)}}">
<p id="section-{{section.label}}" class="truncate my-3">{{ section.label }}</p></a>
{% if not section.active_interpretations %}
<p class="ml-3 my-3 italic text-sm">This section is empty</p>
{% else %}
<div class="ql-snow truncate md:max-w-xl">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{display_tags(section.approved_interpretation.text)|safe }}</p>
</div>
</div>
<div
class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm"
>Interpretation by
<a
href="{{url_for('user.profile',user_id=section.approved_interpretation.user.id)}}"
class="text-blue-500 {% if section.approved_interpretation.user.is_deleted %}line-through{% endif %}"
>{{section.approved_interpretation.user.username}}</a
>
on {{section.approved_interpretation.created_at.strftime('%B %d,
%Y')}}</span
>
<button
data-tooltip-target="tooltip-click"
data-tooltip-trigger="click"
id="copyLinkButton"
type="button"
class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white"
data-link="{{ build_qa_url(section.approved_interpretation) }}">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" />
</svg>
</button>
<div
id="tooltip-click"
role="tooltip"
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
Link copied!
<div class="tooltip-arrow" data-popper-arrow></div>
</div>
</div>
<!--Comments-->
{% if not section.approved_comments %}
<p>No comments for current section</p>
{% else %}
<div
id="accordion-comments-collapse-{{loop.index}}"
data-accordion="collapse">
<h2
id="accordion-comments-collapse-{{loop.index}}-heading-{{loop.index}}">
<button
type="button"
class="flex items-center bg-inherit justify-start w-full p-5 font-medium text-left"
data-accordion-target="#accordion-comments-collapse-{{loop.index}}-body-{{loop.index}}"
aria-expanded="false"
aria-controls="accordion-collapse-body-1">
<svg
data-accordion-icon
class="w-6 h-6 rotate-180 shrink-0"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
<span><i>Comments:</i></span>
</button>
</h2>
<div
id="accordion-comments-collapse-{{loop.index}}-body-{{loop.index}}"
class="hidden"
aria-labelledby="accordion-collapse-heading-{{loop.index}}">
{% for comment in section.approved_comments %}
<div class="p-5 ml-6">
<div class="dark:text-white h-30">
<div class="ql-snow mb-2 truncate md:max-w-xl">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{ display_tags(comment.text)|safe }}</p>
</div>
</div>
</div>
<div
class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm"
>Created by
<a
href="{{url_for('user.profile',user_id=comment.user.id)}}"
class="text-blue-500 {% if comment.user.is_deleted %}line-through{% endif %}"
>{{comment.user.username}}</a
>
on {{comment.created_at.strftime('%B %d, %Y')}}</span
>
<button
data-tooltip-target="tooltip-click"
data-tooltip-trigger="click"
id="copyLinkButton"
type="button"
class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white"
data-link="{{ build_qa_url(section.approved_interpretation) }}">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" />
</svg>
</button>
<div
id="tooltip-click"
role="tooltip"
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
Link copied!
<div class="tooltip-arrow" data-popper-arrow></div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %} {% endif %}
</div>
</div>
<!-- prettier-ignore -->
{% endfor %}
{% endif %}
{% endfor %}
{% else %}
<!-- prettier-ignore -->
{% for section in collection.active_sections %}
<!-- prettier-ignore -->
<a href="{{url_for('book.interpretation_view', book_id=book.id, section_id=section.id)}}">
<!-- prettier-ignore -->
<p id="section-{{section.label}}" class="truncate my-3"> {{ section.label }} </p></a >
{% if not section.active_interpretations %}
<p class="ml-3 my-3 italic text-sm">This section is empty</p>
{% else %}
<div class="ql-snow truncate md:max-w-xl mb-3">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{ display_tags(section.approved_interpretation.text)|safe }}</p>
</div>
</div>
<!-- prettier-ignore -->
<div class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm"
>Interpretation by
<a
href="{{url_for('user.profile',user_id=section.approved_interpretation.user.id)}}"
class="text-blue-500 {% if section.approved_interpretation.user.is_deleted %}line-through{% endif %}"
>{{section.approved_interpretation.user.username}}</a
>
on {{section.approved_interpretation.created_at.strftime('%B %d,
%Y')}}</span
>
<button
data-tooltip-target="tooltip-click"
data-tooltip-trigger="click"
id="copyLinkButton"
type="button"
class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white"
data-link="{{ build_qa_url(section.approved_interpretation) }}">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" />
</svg>
</button>
<div
id="tooltip-click"
role="tooltip"
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
Link copied!
<div class="tooltip-arrow" data-popper-arrow></div>
</div>
</div>
<!--Comments-->
{% if not section.approved_comments %}
<div class="mb-3">
<p>No comments for current section</p>
</div>
{% else %}
<div
id="accordion-comments-collapse-nest{{loop.index}}"
data-accordion="collapse"
class="mb-3">
<h2
id="accordion-comments-collapse-nest{{loop.index}}-heading-{{loop.index}}">
<button
type="button"
class="flex items-center bg-inherit justify-start w-full p-5 font-medium text-left"
data-accordion-target="#accordion-comments-collapse-nest{{loop.index}}-body-{{loop.index}}"
aria-expanded="false"
aria-controls="accordion-collapse-body-1">
<svg
data-accordion-icon
class="w-6 h-6 rotate-180 shrink-0"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
<span><i>Comments:</i></span>
</button>
</h2>
<div
id="accordion-comments-collapse-nest{{loop.index}}-body-{{loop.index}}"
class="hidden"
aria-labelledby="accordion-collapse-heading-1">
{% for comment in section.approved_comments %}
<div class="p-5 ml-6">
<div class="dark:text-white h-30">
<div class="ql-snow mb-2 truncate md:max-w-xl">
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
<p>{{ display_tags(comment.text)|safe }}</p>
</div>
</div>
</div>
<div
class="flex w-full ml-auto align-center justify-between space-x-3 border-t py-3">
<span class="text-sm"
>Created by
<a
href="{{url_for('user.profile',user_id=comment.user.id)}}"
class="text-blue-500 {% if comment.user.is_deleted %}line-through{% endif %}"
>{{comment.user.username}}</a
>
on {{comment.created_at.strftime('%B %d, %Y')}}</span
>
<button
data-tooltip-target="tooltip-click"
data-tooltip-trigger="click"
id="copyLinkButton"
type="button"
class="hover:dark:text-white hover:text-black focus:ring-2 rounded-full font-medium text-sm p-2.5 text-center inline-flex items-center dark:hover:text-white"
data-link="{{ build_qa_url(section.approved_interpretation) }}">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" />
</svg>
</button>
<div
id="tooltip-click"
role="tooltip"
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
Link copied!
<div class="tooltip-arrow" data-popper-arrow></div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %} {% endif %} {% endfor %} {% endif %}

View File

@ -0,0 +1,87 @@
<div class="ml-6">
{% if not collection.is_leaf %}
<!-- if collection has sub_collection make for loop for it -->
<!-- Nested accordion -->
{% for sub_collection in collection.children if not
sub_collection.is_deleted%}
<div id="accordion-nested-collapse" data-accordion="open">
<!-- prettier-ignore -->
<div class="flex items-center justify-start w-full font-medium text-left text-gray-500 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800 dark:text-gray-400">
<button
class="bg-inherit"
type="button"
data-accordion-target="#accordion-nested-collapse-body-{{sub_collection.parent.id}}-{{sub_collection.id}}"
aria-expanded="true"
aria-controls="accordion-nested-collapse-body-{{sub_collection.parent.id}}-{{sub_collection.id}}">
<!-- prettier-ignore -->
<svg data-accordion-icon class="w-6 h-6 shrink-0" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path> </svg>
</button>
<!-- prettier-ignore -->
<a id="accordion-nested-collapse-heading-{{sub_collection.parent.id}}-{{sub_collection.id}}" class="text-black dark:text-white">
<form id="rename-sub-collection-label-form-{{sub_collection.id}}" data-book-id="{{book.id}}" data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" method="post" class="mb-0">
{{ form_hidden_tag() }}
<!-- prettier-ignore -->
<input class="bg-inherit border-none" value="{{sub_collection.label}}" type="text" name="label" id="edit-sub-collection-label-{{sub_collection.id}}" placeholder="Sub collection label" required readonly />
<button name="submit" type="submit"></button>
</form>
</a>
</div>
<!-- prettier-ignore -->
<svg id="dropdownSubCollectionContextButton{{sub_collection.id}}" data-dropdown-toggle="dropdown" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 0 0" stroke-width="1.5" stroke="none" class="w-0 h-0"></svg>
<!-- prettier-ignore -->
<div data="sub-collection-context-menu-{{sub_collection.id}}" id="dropdown" class="z-10 hidden bg-white divide-y divide-gray-800 border border-gray-800 dark:border-none dark:divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
{% if current_user.is_authenticated %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" id="callAddSectionModal" data-modal-target="add-section-modal" data-modal-toggle="add-section-modal" data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> New Section </button>
</li>
<li>
<button type="button" id="callAddSubCollectionModal" data-modal-target="add-sub-collection-modal" data-modal-toggle="add-sub-collection-modal" data-collection-id="{{sub_collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> New Subcollection </button>
</li>
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" id="rename-sub-collection-button-{{sub_collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> Rename Sub Collection </button>
</li>
<li>
<button type="button" id="callDeleteSubCollectionModal" data-modal-target="delete-sub-collection-modal" data-modal-toggle="delete-sub-collection-modal" data-collection-id="{{collection.id}}" data-sub-collection-id="{{sub_collection.id}}" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> Delete Sub Collection </button>
</li>
</ul>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> Export Sub Collection </button>
</li>
</ul>
{% else %}
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<button type="button" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"> Connect your wallet to do this </button>
</li>
</ul>
{% endif %}
</div>
<!-- prettier-ignore -->
<div id="accordion-nested-collapse-body-{{sub_collection.parent.id}}-{{sub_collection.id}}" class="hidden" aria-labelledby="accordion-nested-collapse-heading-{{sub_collection.id}}">
{% if sub_collection.children %}
{{recursive_render("book/components/sub_collection_tab_content.html",sub_collection,book)|safe}}
{% else %}
<div class="ml-6">
<!-- here comes for loop for all section in this sub_collection-->
{% for section in sub_collection.active_sections %}
{% include 'book/components/section_tab_content.html' %}
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% endfor %}
<!-- End: Nested accordion -->
{% else %}
<!-- if collection doesn't have sub_collection -->
<div class="ml-6">
<!-- here comes for loop for all section in this collection-->
{% for section in collection.active_sections %} {% include
'book/components/section_tab_content.html' %} {% endfor %}
</div>
{% endif %}
</div>

View File

@ -88,7 +88,6 @@ def collection_create(book_id: int, collection_id: int | None = None):
)
if collection_id:
collection.parent_id = collection_id
collection.is_leaf = True
log(log.INFO, "Create collection [%s]. Book: [%s]", collection, book.id)
collection.save()