mirror of https://github.com/logos-co/open-law.git
Merge branch 'develop' into svyat/feat/local_permission
This commit is contained in:
commit
930295af7b
|
@ -24,6 +24,7 @@
|
|||
"pytest",
|
||||
"scrf",
|
||||
"siwe",
|
||||
"sortablejs",
|
||||
"sqlalchemy",
|
||||
"tailwindcss",
|
||||
"upvoted",
|
||||
|
|
|
@ -36,11 +36,15 @@ class Collection(BaseModel):
|
|||
|
||||
@property
|
||||
def active_sections(self):
|
||||
return [section for section in self.sections if not section.is_deleted]
|
||||
items = [section for section in self.sections if not section.is_deleted]
|
||||
items.sort(key=lambda item: item.position)
|
||||
return items
|
||||
|
||||
@property
|
||||
def active_children(self):
|
||||
return [child for child in self.children if not child.is_deleted]
|
||||
items = [child for child in self.children if not child.is_deleted]
|
||||
items.sort(key=lambda item: item.position)
|
||||
return items
|
||||
|
||||
@property
|
||||
def book_id(self):
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -13,3 +13,10 @@
|
|||
* @copyright Chen, Yi-Cyuan 2015-2018
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**!
|
||||
* Sortable 1.15.0
|
||||
* @author RubaXa <trash@rubaxa.org>
|
||||
* @author owenm <owen23355@gmail.com>
|
||||
* @license MIT
|
||||
*/
|
||||
|
|
|
@ -18,16 +18,12 @@
|
|||
{% endif %}
|
||||
|
||||
<div class="flex overflow-hidden">
|
||||
<div
|
||||
id="accordion-collapse"
|
||||
data-accordion="open"
|
||||
class="p-3 w-2/6 border-t border-r border-gray-200 dark:border-gray-700 overflow-y-scroll h-box">
|
||||
<!-- prettier-ignore -->
|
||||
<div id="accordion-collapse" data-accordion="open" class="p-3 w-2/6 border-t border-r border-gray-200 dark:border-gray-700 overflow-y-scroll h-box">
|
||||
<div class="flex justify-between">
|
||||
<div class="flex dark:text-white">
|
||||
<svg id="tabGoBackButton" 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 cursor-pointer"> <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" /> </svg>
|
||||
<h1 class="text-l font-extrabold dark:text-white ml-4 mb-3">
|
||||
Table of contents
|
||||
</h1>
|
||||
<h1 class="text-l font-extrabold dark:text-white ml-4 mb-3"> Table of contents </h1>
|
||||
</div>
|
||||
{% if has_permission(book, Access.U) %}
|
||||
<div class="flex text-black dark:text-white">
|
||||
|
@ -42,17 +38,22 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<!-- prettier-ignore -->
|
||||
{% for collection in book.versions[-1].children_collections if not collection.is_root and not collection.is_deleted %}
|
||||
<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">
|
||||
<div
|
||||
{% if not collection.active_children and not collection.active_sections %}id="empty-dnd-entity"
|
||||
{% elif collection.active_children %}data-dnd="dnd-sub-collection"
|
||||
{% elif collection.active_sections %}id="draggableSectionItems"{% endif %}
|
||||
data-entity-type="collection"
|
||||
data-entity-id="{{collection.id}}" class="filter">
|
||||
<div data-entity-type="collection"
|
||||
data-entity-id="{{collection.id}}" 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-{{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>
|
||||
<button href="#collection-{{collection.label}}" id="accordion-collapse-heading-{{collection.id}}" class=" text-black dark:text-white ">
|
||||
<button href="#collection-{{collection.label}}" 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-{{collection.id}}" placeholder="Collection label" required readonly/>
|
||||
|
@ -63,68 +64,29 @@
|
|||
<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-{{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 %}
|
||||
{% set access_to_create_collections = has_permission(collection, Access.C) %}
|
||||
{% set access_to_update_collections = has_permission(collection, Access.U) %}
|
||||
{% set access_to_delete_collections = has_permission(collection, Access.D) %}
|
||||
{% set access_to_create_section = has_permission(collection, Access.C, EntityType.SECTION) %}
|
||||
|
||||
{% if access_to_create_collections or access_to_update_collections %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_create_collections %}
|
||||
<li>
|
||||
<button type="button" data-modal-target="add-collection-modal" data-modal-toggle="add-collection-modal" class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">New Collection</button>
|
||||
</li>
|
||||
{% if not collection.is_leaf %}
|
||||
<li>
|
||||
<button type="button" id="callAddSubCollectionModal" data-modal-target="add-sub-collection-modal" data-modal-toggle="add-sub-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">New Subcollection</button>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if access_to_create_section %}
|
||||
{% if collection.active_children|length ==0 or collection.active_children|length ==0 and collection.is_leaf %}
|
||||
<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="_" 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>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if access_to_update_collections or access_to_delete_collections %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_update_collections %}
|
||||
<li>
|
||||
<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>
|
||||
{% endif %}
|
||||
{% if access_to_delete_collections %}
|
||||
<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>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<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 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 you wallet to do this</button>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% include 'book/components/collection_context_menu.html' %}
|
||||
</div>
|
||||
<!-- prettier-ignore -->
|
||||
<div id="accordion-collapse-body-{{collection.id}}" class="hidden" aria-labelledby="accordion-collapse-heading-{{collection.id}}">
|
||||
{% if collection.active_children %}
|
||||
<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>
|
||||
{% elif collection.active_sections %}
|
||||
<div id="accordion-collapse-body-{{collection.id}}" class="hidden" aria-labelledby="accordion-collapse-heading-{{collection.id}}" >
|
||||
<div id="draggableSectionItems" data-entity-id="{{collection.id}}" data-entity-type="collection" data-book-id="{{book.id}}">
|
||||
{% for section in collection.active_sections %}
|
||||
{% include 'book/components/section_tab_content.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div id="accordion-collapse-body-{{collection.id}}" class="hidden" aria-labelledby="accordion-collapse-heading-{{collection.id}}" >
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="p-3 px-6 w-4/6 dark:text-white overflow-y-scroll h-box ">
|
||||
<!-- Here start book-preview on right side-->
|
||||
<div class="p-3 px-6 w-4/6 dark:text-white overflow-y-scroll h-box ">
|
||||
<p class="text-xs mb-3">Created by <a href="{{url_for('user.profile',user_id=book.owner.id)}}" class=" text-blue-500 {% if book.owner.is_deleted %}line-through{% endif %}">{{book.owner.username}}</a> on {{book.created_at.strftime('%B %d, %Y')}}. Last updated on {{book.created_at.strftime('%B %d, %Y')}}</p>
|
||||
<div class="flex justify-between item-center">
|
||||
<h1 class="hidden md:inline font-extrabold text-lg dark:text-white">{{book.label}}</h1>
|
||||
|
@ -156,7 +118,7 @@
|
|||
<p class=" text-sm mb-3">{% if book.about==None %}About text{% else %}{{book.about}}{% endif %}</p>
|
||||
{% for collection in book.versions[-1].children_collections if not collection.is_root and not collection.is_deleted %}
|
||||
<p class="my-3 underline" id="collection-{{collection.label}}">#{{collection.label}}</p>
|
||||
{% if not collection.is_leaf and not collection.active_children %}
|
||||
{% if not collection.active_sections and not collection.active_children %}
|
||||
<p class="ml-3 my-3 italic text-sm">Collection is empty</p>
|
||||
{% endif %}
|
||||
{{recursive_render("book/components/sub_collection_preview_content.html",collection,book)|safe}}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
{% if current_user.is_authenticated %}
|
||||
<!-- prettier-ignore -->
|
||||
{% set access_to_create_collections =has_permission(collection, Access.C) %}
|
||||
{% set access_to_update_collections =has_permission(collection, Access.U) %}
|
||||
{% set access_to_delete_collections =has_permission(collection, Access.D) %}
|
||||
{% set access_to_create_section =has_permission(collection, Access.C, EntityType.SECTION) %}
|
||||
{% if access_to_create_collections or access_to_update_collections %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_create_collections %}
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
data-modal-target="add-collection-modal"
|
||||
data-modal-toggle="add-collection-modal"
|
||||
class="w-full block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white">
|
||||
New Collection
|
||||
</button>
|
||||
</li>
|
||||
{% if collection.active_children or not collection.active_sections%}
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
id="callAddSubCollectionModal"
|
||||
data-modal-target="add-sub-collection-modal"
|
||||
data-modal-toggle="add-sub-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">
|
||||
New Subcollection
|
||||
</button>
|
||||
</li>
|
||||
<!-- prettier-ignore -->
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if access_to_create_section %}
|
||||
{% if not collection.active_children or not collection.active_children and collection.active_sections %}
|
||||
<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="_"
|
||||
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>
|
||||
<!-- prettier-ignore -->
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_update_collections or access_to_delete_collections %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_update_collections %}
|
||||
<li>
|
||||
<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>
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_delete_collections %}
|
||||
<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>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<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 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 you wallet to do this
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
|
@ -0,0 +1,47 @@
|
|||
<!-- prettier-ignore -->
|
||||
{% if current_user.is_authenticated %}
|
||||
{% set access_to_create_sections = has_permission(section, Access.C) %}
|
||||
{% set access_to_update_sections = has_permission(section, Access.U) %}
|
||||
{% set access_to_delete_sections = has_permission(section, Access.D) %}
|
||||
{% if access_to_update_sections or access_to_delete_sections %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_update_sections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_delete_sections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<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 %}
|
|
@ -1,104 +1,21 @@
|
|||
<div class="">
|
||||
<button
|
||||
type="button"
|
||||
href="#section-{{section.label}}"
|
||||
id="section-heading-{{section.id}}"
|
||||
class="text-gray-500 dark:text-gray-400">
|
||||
<div
|
||||
class="flex flex-col ml-6"
|
||||
data-entity-id="{{section.id}}"
|
||||
data-entity-type="section"
|
||||
data-book-id="{{book.id}}">
|
||||
<!-- prettier-ignore -->
|
||||
<button type="button" href="#section-{{section.label}}" id="section-heading-{{section.id}}" class="text-gray-500 dark:text-gray-400 w-max">
|
||||
<!-- 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 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" class="inline-block w-auto">
|
||||
{{ 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
|
||||
/>
|
||||
<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 %}
|
||||
{% set access_to_create_sections = has_permission(section, Access.C) %}
|
||||
{% set access_to_update_sections = has_permission(section, Access.U) %}
|
||||
{% set access_to_delete_sections = has_permission(section, Access.D) %}
|
||||
|
||||
{% if access_to_update_sections or access_to_delete_sections %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_update_sections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
|
||||
{% if access_to_delete_sections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<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 %}
|
||||
<!-- prettier-ignore -->
|
||||
<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>
|
||||
<!-- prettier-ignore -->
|
||||
<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">
|
||||
{% include 'book/components/section_context_menu.html' %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<!-- prettier-ignore -->
|
||||
{% if current_user.is_authenticated %}
|
||||
{% set access_to_create_collections =has_permission(sub_collection, Access.C) %}
|
||||
{% set access_to_update_collections= has_permission(sub_collection, Access.U) %}
|
||||
{% set access_to_delete_collections = has_permission(sub_collection, Access.D) %}
|
||||
{% set access_to_create_section = has_permission(collection, Access.C,EntityType.SECTION) %}
|
||||
{% if access_to_create_collections or access_to_update_collections or access_to_create_section %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_create_section and sub_collection.active_sections and not sub_collection.active_children %}
|
||||
<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>
|
||||
<!-- prettier-ignore -->
|
||||
{% elif not sub_collection.active_sections and not sub_collection.active_children %} {% if access_to_create_section %}
|
||||
<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>
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_create_collections %}
|
||||
<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>
|
||||
{% endif %} {% else %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_create_collections %}
|
||||
<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>
|
||||
<!-- prettier-ignore -->
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_update_collections or access_to_delete_collections%}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_update_collections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if access_to_delete_collections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<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 %}
|
|
@ -1,10 +1,12 @@
|
|||
{% if not collection.is_leaf %}
|
||||
{% if not collection.active_sections %}
|
||||
<!-- if collection has sub_collection make for loop for it -->
|
||||
<!-- prettier-ignore -->
|
||||
{% for sub_collection in collection.active_children if not sub_collection.is_deleted%}
|
||||
<p class="my-3" id="collection-{{sub_collection.label}}">
|
||||
##{{sub_collection.label}}
|
||||
</p>
|
||||
{% if not sub_collection.active_sections and not sub_collection.active_children %}
|
||||
<!-- prettier-ignore -->
|
||||
{% if not sub_collection.active_sections and not sub_collection.active_children%}
|
||||
<p class="ml-3 my-3 italic text-sm">This sub collection is empty</p>
|
||||
{% endif %}
|
||||
<!-- prettier-ignore -->
|
||||
|
@ -24,7 +26,10 @@
|
|||
{% else %}
|
||||
<div class="ql-snow truncate md:max-w-xl">
|
||||
<div class="dark:text-white h-30 ql-editor-readonly !px-0">
|
||||
<p>{{display_inline_elements(section.approved_interpretation.text)|safe }}</p>
|
||||
<p>
|
||||
{{display_inline_elements(section.approved_interpretation.text)|safe
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -172,7 +177,9 @@
|
|||
{% 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_inline_elements(section.approved_interpretation.text)|safe }}</p>
|
||||
<p>
|
||||
{{ display_inline_elements(section.approved_interpretation.text)|safe }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- prettier-ignore -->
|
||||
|
|
|
@ -1,10 +1,28 @@
|
|||
<div class="ml-6">
|
||||
{% if not collection.is_leaf %}
|
||||
<!-- prettier-ignore -->
|
||||
<div
|
||||
class="ml-6"
|
||||
data-dnd="dnd-sub-collection"
|
||||
{% if collection %}
|
||||
data-entity-type="collection"
|
||||
data-entity-id="{{collection.id}}"
|
||||
{% endif %}
|
||||
{% if sub_collection %}
|
||||
data-entity-type="sub_collection"
|
||||
data-entity-id="{{sub_collection.id}}"
|
||||
{% endif %}
|
||||
data-book-id="{{book.id}}"
|
||||
>
|
||||
{% if collection.active_children %}
|
||||
<!-- if collection has sub_collection make for loop for it -->
|
||||
<!-- Nested accordion -->
|
||||
<!-- prettier-ignore -->
|
||||
{% for sub_collection in collection.active_children if not sub_collection.is_deleted%}
|
||||
<div id="accordion-nested-collapse" data-accordion="open">
|
||||
<div
|
||||
id="accordion-nested-collapse"
|
||||
data-accordion="open"
|
||||
data-entity-id="{{sub_collection.id}}"
|
||||
data-entity-type="sub_collection"
|
||||
data-book-id="{{book.id}}">
|
||||
<!-- 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
|
||||
|
@ -30,77 +48,21 @@
|
|||
<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 %}
|
||||
{% set access_to_create_collections = has_permission(sub_collection, Access.C) %}
|
||||
{% set access_to_update_collections = has_permission(sub_collection, Access.U) %}
|
||||
{% set access_to_delete_collections = has_permission(sub_collection, Access.D) %}
|
||||
{% set access_to_create_section = has_permission(collection, Access.C, EntityType.SECTION) %}
|
||||
|
||||
{% if access_to_create_collections or access_to_update_collections or access_to_create_section %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_create_section and sub_collection.is_leaf and not sub_collection.active_children %}
|
||||
<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>
|
||||
{% elif not sub_collection.is_leaf and not sub_collection.active_children %}
|
||||
{% if access_to_create_section %}
|
||||
<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>
|
||||
{% endif %}
|
||||
{% if access_to_create_collections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if access_to_create_collections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if access_to_update_collections or access_to_delete_collections %}
|
||||
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
|
||||
{% if access_to_update_collections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
{% if access_to_delete_collections %}
|
||||
<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>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<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 %}
|
||||
{% include 'book/components/sub_collection_context_menu.html' %}
|
||||
</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.active_children %}
|
||||
{{recursive_render("book/components/sub_collection_tab_content.html",sub_collection,book)|safe}}
|
||||
{% else %}
|
||||
<div class="ml-6">
|
||||
{% elif sub_collection.active_sections %}
|
||||
<div id="draggableSectionItems" data-entity-id="{{sub_collection.id}}" data-entity-type="sub_collection" data-book-id="{{book.id}}">
|
||||
<!-- 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>
|
||||
{% else %}
|
||||
<div id="empty-dnd-entity" data-entity-type="sub_collection" data-entity-id="{{sub_collection.id}}"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -108,10 +70,16 @@
|
|||
<!-- End: Nested accordion -->
|
||||
{% else %}
|
||||
<!-- if collection doesn't have sub_collection -->
|
||||
<div class="ml-6">
|
||||
<div
|
||||
class="ml-6"
|
||||
id="draggableSectionItems"
|
||||
data-entity-id="{{collection.id}}"
|
||||
data-entity-type="collection">
|
||||
<!-- here comes for loop for all section in this collection-->
|
||||
{% for section in collection.active_sections %} {% include
|
||||
'book/components/section_tab_content.html' %} {% endfor %}
|
||||
{% for section in collection.active_sections %}
|
||||
<!-- prettier-ignore -->
|
||||
{% include 'book/components/section_tab_content.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -239,25 +239,23 @@ def change_collection_position(book_id: int, collection_id: int):
|
|||
collection.parent_id = collection_id
|
||||
|
||||
if new_parent.active_children:
|
||||
collections_to_edit = m.Collection.query.filter(
|
||||
m.Collection.parent_id == new_parent.id,
|
||||
m.Collection.position >= new_position,
|
||||
).all()
|
||||
if collections_to_edit:
|
||||
log(log.INFO, "Calculate new positions of collections in [%s]", collection)
|
||||
for child in collections_to_edit:
|
||||
child: m.Collection
|
||||
if child.position >= new_position:
|
||||
child.position += 1
|
||||
child.save(False)
|
||||
|
||||
collections_to_edit = (
|
||||
m.Collection.query.filter(
|
||||
m.Collection.parent_id == new_parent.id,
|
||||
m.Collection.id != collection.id,
|
||||
)
|
||||
.order_by(m.Collection.position)
|
||||
.all()
|
||||
)
|
||||
collections_to_edit.insert(new_position, collection)
|
||||
log(
|
||||
log.INFO,
|
||||
"Set new position [%s] of collection [%s]",
|
||||
new_position,
|
||||
collection,
|
||||
"Calculate new positions of collections in [%s]",
|
||||
new_parent,
|
||||
)
|
||||
collection.position = new_position
|
||||
for position in range(len(collections_to_edit)):
|
||||
collections_to_edit[position].position = position
|
||||
collections_to_edit[position].save(False)
|
||||
else:
|
||||
log(
|
||||
log.INFO,
|
||||
|
@ -268,5 +266,5 @@ def change_collection_position(book_id: int, collection_id: int):
|
|||
collection.position = 1
|
||||
|
||||
log(log.INFO, "Apply position changes on [%s]", collection)
|
||||
collection.save()
|
||||
db.session.commit()
|
||||
return {"message": "success"}
|
||||
|
|
|
@ -151,20 +151,19 @@ def change_section_position(book_id: int, section_id: int):
|
|||
section.collection_id = collection_id
|
||||
|
||||
if collection.active_sections:
|
||||
sections_to_edit = m.Section.query.filter(
|
||||
m.Section.collection_id == collection.id,
|
||||
m.Section.position >= new_position,
|
||||
).all()
|
||||
if sections_to_edit:
|
||||
log(log.INFO, "Calculate new positions of sections in [%s]", collection)
|
||||
for child in sections_to_edit:
|
||||
child: m.Section
|
||||
if child.position >= new_position:
|
||||
child.position += 1
|
||||
child.save(False)
|
||||
|
||||
log(log.INFO, "Set new position [%s] of section [%s]", new_position, section)
|
||||
section.position = new_position
|
||||
sections_to_edit = (
|
||||
m.Section.query.filter(
|
||||
m.Section.collection_id == collection.id,
|
||||
m.Section.id != section.id,
|
||||
)
|
||||
.order_by(m.Section.position)
|
||||
.all()
|
||||
)
|
||||
sections_to_edit.insert(new_position, section)
|
||||
log(log.INFO, "Calculate new positions of sections in [%s]", collection)
|
||||
for position in range(len(sections_to_edit)):
|
||||
sections_to_edit[position].position = position
|
||||
sections_to_edit[position].save(False)
|
||||
else:
|
||||
log(
|
||||
log.INFO,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/lodash.debounce": "^4.0.7",
|
||||
"@types/sortablejs": "^1.15.1",
|
||||
"ethers": "5.5.3",
|
||||
"flowbite": "^1.6.4",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
|
@ -25,6 +26,7 @@
|
|||
"postcss": "^8.4.21",
|
||||
"postcss-loader": "^7.2.4",
|
||||
"postcss-preset-env": "^8.3.1",
|
||||
"sortablejs": "^1.15.0",
|
||||
"style-loader": "^3.3.2",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^5.0.4",
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// Default SortableJS
|
||||
import Sortable from 'sortablejs';
|
||||
|
||||
export function initDnD() {
|
||||
const divsForSectionsDnD: NodeListOf<HTMLDivElement> =
|
||||
document.querySelectorAll('#draggableSectionItems');
|
||||
const divsForSubCollectionsDnD: NodeListOf<HTMLDivElement> =
|
||||
document.querySelectorAll('[data-dnd="dnd-sub-collection"]');
|
||||
const divsAreEmpty = document.querySelectorAll('#empty-dnd-entity');
|
||||
divsForSectionsDnD.forEach((div: HTMLDivElement) =>
|
||||
Sortable.create(div, {
|
||||
group: {
|
||||
name: 'sections',
|
||||
pull: true,
|
||||
put: ['sections'],
|
||||
},
|
||||
animation: 100,
|
||||
onEnd: async function (/**Event*/ evt) {
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
const bookId = itemEl.getAttribute('data-book-id');
|
||||
const sectionId = itemEl.getAttribute('data-entity-id');
|
||||
if (bookId && sectionId) {
|
||||
const requestUrl = `/book/${bookId}/${sectionId}/section/change_position`;
|
||||
const response = await fetch(requestUrl, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
position: evt.newDraggableIndex,
|
||||
collection_id: evt.to.getAttribute('data-entity-id'),
|
||||
}),
|
||||
});
|
||||
if (response.status === 200) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
divsForSubCollectionsDnD.forEach((div: HTMLDivElement) =>
|
||||
Sortable.create(div, {
|
||||
group: {
|
||||
name: 'sub_collections',
|
||||
pull: true,
|
||||
put: ['sub_collections'],
|
||||
},
|
||||
animation: 100,
|
||||
onEnd: async function (/**Event*/ evt) {
|
||||
var itemEl = evt.item; // dragged HTMLElement
|
||||
const bookId = itemEl.getAttribute('data-book-id');
|
||||
const collectionId = itemEl.getAttribute('data-entity-id');
|
||||
if (bookId && collectionId) {
|
||||
const requestUrl = `/book/${bookId}/${collectionId}/collection/change_position`;
|
||||
const response = await fetch(requestUrl, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
position: evt.newDraggableIndex,
|
||||
collection_id: evt.to.getAttribute('data-entity-id'),
|
||||
}),
|
||||
});
|
||||
if (response.status === 200) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
divsAreEmpty.forEach((div: HTMLDivElement) =>
|
||||
Sortable.create(div, {
|
||||
group: {
|
||||
name: 'empty',
|
||||
pull: false,
|
||||
put: ['sub_collections', 'sections'],
|
||||
},
|
||||
animation: 100,
|
||||
fallbackOnBody: true,
|
||||
swapThreshold: 20,
|
||||
filter: '.filter',
|
||||
}),
|
||||
);
|
||||
}
|
|
@ -27,6 +27,7 @@ import {copyLink} from './copyLink';
|
|||
import {quickSearch} from './quickSearch';
|
||||
import {flash} from './flash';
|
||||
import {slashSearch} from './slashSearch';
|
||||
import {initDnD} from './drag_and_drop';
|
||||
import {editInterpretations} from './editInterpretations';
|
||||
import {deleteInterpretation} from './deleteInterpretation';
|
||||
import {indeterminateInputs} from './indeterminateInputs';
|
||||
|
@ -61,6 +62,7 @@ copyLink();
|
|||
quickSearch();
|
||||
flash();
|
||||
slashSearch();
|
||||
initDnD();
|
||||
editInterpretations();
|
||||
deleteInterpretation();
|
||||
indeterminateInputs();
|
||||
|
|
|
@ -1,40 +1,38 @@
|
|||
@tailwind base;
|
||||
/* Firefox */
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: inherit gray ;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: inherit gray;
|
||||
}
|
||||
|
||||
/* Chrome, Edge, and Safari */
|
||||
*::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: inherit;
|
||||
border-radius: 1px;
|
||||
background: inherit;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: gray;
|
||||
border-radius: 14px;
|
||||
border: 1px solid inherit;
|
||||
background-color: gray;
|
||||
border-radius: 14px;
|
||||
border: 1px solid inherit;
|
||||
}
|
||||
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
|
||||
.text-danger {
|
||||
color: red;
|
||||
color: red;
|
||||
}
|
||||
.h-box{
|
||||
height: calc(100vh - 150px);
|
||||
.h-box {
|
||||
height: calc(100vh - 150px);
|
||||
}
|
||||
.w-box{
|
||||
width: calc(100vw - 255px);
|
||||
.w-box {
|
||||
width: calc(100vw - 255px);
|
||||
}
|
||||
.mt-135{
|
||||
margin-top:135px;
|
||||
.mt-135 {
|
||||
margin-top: 135px;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,11 +52,14 @@ def test_change_collection_ordering(client):
|
|||
collection: m.Collection = db.session.get(m.Collection, 3)
|
||||
assert current_ordering[collection.id] != collection.position
|
||||
assert collection.position == new_position
|
||||
for collection in m.Collection.query.filter_by(parent_id=root_collection.id).all():
|
||||
if collection.position < new_position:
|
||||
assert current_ordering[collection.id] == collection.position
|
||||
elif collection.position > new_position:
|
||||
assert current_ordering[collection.id] + 1 == collection.position
|
||||
collections = (
|
||||
m.Collection.query.filter_by(parent_id=collection.parent_id)
|
||||
.order_by(m.Collection.position)
|
||||
.all()
|
||||
)
|
||||
assert collections[new_position] == collection
|
||||
assert collections[new_position - 1].position == collection.position - 1
|
||||
assert collections[new_position + 1].position == collection.position + 1
|
||||
|
||||
collection: m.Collection = db.session.get(m.Collection, 3)
|
||||
collection_1, _ = create_sub_collection(client, book.id, root_collection.id)
|
||||
|
@ -126,11 +129,14 @@ def test_change_section_ordering(client):
|
|||
section: m.Section = db.session.get(m.Section, 3)
|
||||
assert current_ordering[section.id] != section.position
|
||||
assert section.position == new_position
|
||||
for section in m.Section.query.filter_by(collection_id=collection_1.id).all():
|
||||
if section.position < new_position:
|
||||
assert current_ordering[section.id] == section.position
|
||||
elif section.position > new_position:
|
||||
assert current_ordering[section.id] + 1 == section.position
|
||||
sections = (
|
||||
m.Section.query.filter_by(collection_id=collection_1.id)
|
||||
.order_by(m.Section.position)
|
||||
.all()
|
||||
)
|
||||
assert sections[new_position] == section
|
||||
assert sections[new_position - 1].position == section.position - 1
|
||||
assert sections[new_position + 1].position == section.position + 1
|
||||
|
||||
new_position = 999
|
||||
assert section.collection_id == collection_1.id
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node"
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
},
|
||||
"include": ["src/**/*.ts*"],
|
||||
"exclude": ["node_modules", "dist", "lib"]
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -1172,6 +1172,11 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/sortablejs@^1.15.1":
|
||||
version "1.15.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/sortablejs/-/sortablejs-1.15.1.tgz#123abafbe936f754fee5eb5b49009ce1f1075aa5"
|
||||
integrity sha512-g/JwBNToh6oCTAwNS8UGVmjO7NLDKsejVhvE4x1eWiPTC3uCuNsa/TD4ssvX3du+MLiM+SHPNDuijp8y76JzLQ==
|
||||
|
||||
"@types/ws@^8.5.1":
|
||||
version "8.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
|
||||
|
@ -3618,6 +3623,11 @@ sockjs@^0.3.24:
|
|||
uuid "^8.3.2"
|
||||
websocket-driver "^0.7.4"
|
||||
|
||||
sortablejs@^1.15.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.15.0.tgz#53230b8aa3502bb77a29e2005808ffdb4a5f7e2a"
|
||||
integrity sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==
|
||||
|
||||
source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
|
|
Loading…
Reference in New Issue