mirror of https://github.com/logos-co/open-law.git
Merge pull request #16 from Simple2B/kostia/feture/bread_crumbs_navigation
Kostia/feture/bread crumbs navigation
This commit is contained in:
commit
9c4f8962f8
|
@ -1,2 +1,3 @@
|
||||||
# flake8: noqa F401
|
# flake8: noqa F401
|
||||||
from .pagination import create_pagination
|
from .pagination import create_pagination
|
||||||
|
from .breadcrumbs import create_breadcrumbs
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
from flask import url_for
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
|
from app import models as m, db
|
||||||
|
from app import schema as s
|
||||||
|
|
||||||
|
|
||||||
|
def create_breadcrumbs(
|
||||||
|
book_id: int,
|
||||||
|
collection_path: tuple[int],
|
||||||
|
section_id: int = 0,
|
||||||
|
interpretation_id: int = 0,
|
||||||
|
) -> list[s.BreadCrumb]:
|
||||||
|
"""
|
||||||
|
How breadcrumbs look like:
|
||||||
|
|
||||||
|
Book List -> Book Name -> Top Level Collection -> SubCollection -> Section -> Interpretation
|
||||||
|
|
||||||
|
- If i am not owner of a book
|
||||||
|
John's books -> Book Name -> Top Level Collection -> SubCollection -> Section -> Interpretation
|
||||||
|
|
||||||
|
- If i am owner
|
||||||
|
My Books -> Book Title -> Part I -> Chapter X -> Paragraph 1.7 -> By John
|
||||||
|
"""
|
||||||
|
|
||||||
|
crumples: list[s.BreadCrumb] = []
|
||||||
|
book: m.Book = db.session.get(m.Book, book_id)
|
||||||
|
if current_user.is_authenticated and book.user_id == current_user.id:
|
||||||
|
# My Book
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.MyBookList,
|
||||||
|
url=url_for("book.my_books"),
|
||||||
|
label="My Books",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
# Not mine book
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.AuthorBookList,
|
||||||
|
url="#",
|
||||||
|
label=book.owner.username + "'s books",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.Collection,
|
||||||
|
url=url_for("book.collection_view", book_id=book_id),
|
||||||
|
label=book.label,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
for collection_id in collection_path:
|
||||||
|
if collection_id is None:
|
||||||
|
continue
|
||||||
|
collection: m.Collection = db.session.get(m.Collection, collection_id)
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.Collection,
|
||||||
|
url=url_for(
|
||||||
|
"book.sub_collection_view",
|
||||||
|
book_id=book_id,
|
||||||
|
collection_id=collection_id,
|
||||||
|
),
|
||||||
|
label=collection.label,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
if section_id and collection_path:
|
||||||
|
section: m.Section = db.session.get(m.Section, section_id)
|
||||||
|
if len(collection_path) == 2:
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.Section,
|
||||||
|
url=url_for(
|
||||||
|
"book.section_view",
|
||||||
|
book_id=book_id,
|
||||||
|
collection_id=collection_path[0],
|
||||||
|
sub_collection_id=collection_path[-1],
|
||||||
|
),
|
||||||
|
label=section.label,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.Section,
|
||||||
|
url=url_for(
|
||||||
|
"book.section_view",
|
||||||
|
book_id=book_id,
|
||||||
|
collection_id=collection_path[0],
|
||||||
|
sub_collection_id=collection_path[0],
|
||||||
|
),
|
||||||
|
label=section.label,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
if interpretation_id:
|
||||||
|
interpretation: m.Interpretation = db.session.get(
|
||||||
|
m.Interpretation, interpretation_id
|
||||||
|
)
|
||||||
|
if len(collection_path) == 2:
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.Interpretation,
|
||||||
|
url=url_for(
|
||||||
|
"book.interpretation_view",
|
||||||
|
book_id=book_id,
|
||||||
|
collection_id=collection_path[0],
|
||||||
|
sub_collection_id=collection_path[-1],
|
||||||
|
section_id=section_id,
|
||||||
|
),
|
||||||
|
label=interpretation.label,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
crumples += [
|
||||||
|
s.BreadCrumb(
|
||||||
|
type=s.BreadCrumbType.Interpretation,
|
||||||
|
url=url_for(
|
||||||
|
"book.interpretation_view",
|
||||||
|
book_id=book_id,
|
||||||
|
collection_id=collection_path[0],
|
||||||
|
sub_collection_id=collection_path[0],
|
||||||
|
section_id=section_id,
|
||||||
|
),
|
||||||
|
label=interpretation.label,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
return crumples
|
|
@ -1,3 +1,4 @@
|
||||||
# flake8: noqa F401
|
# flake8: noqa F401
|
||||||
from .pagination import Pagination
|
from .pagination import Pagination
|
||||||
from .user import User
|
from .user import User
|
||||||
|
from .breadcrumbs import BreadCrumbType, BreadCrumb
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import enum
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class BreadCrumbType(enum.StrEnum):
|
||||||
|
"""Bread Crumb Type"""
|
||||||
|
|
||||||
|
MyBookList = "MyBookList"
|
||||||
|
AuthorBookList = "AuthorBookList"
|
||||||
|
Collection = "Collection"
|
||||||
|
Section = "Section"
|
||||||
|
Interpretation = "Interpretation"
|
||||||
|
|
||||||
|
|
||||||
|
class BreadCrumb(BaseModel):
|
||||||
|
"""Bread Crumb for navigation"""
|
||||||
|
|
||||||
|
label: str
|
||||||
|
url: str
|
||||||
|
type: BreadCrumbType
|
File diff suppressed because one or more lines are too long
|
@ -22,9 +22,6 @@
|
||||||
<button id="search-btn" class="cursor-pointer select-none text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Search</button>
|
<button id="search-btn" class="cursor-pointer select-none text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Search</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-span-6 sm:col-span-3 overflow-x-auto shadow-md sm:rounded-lg" id="search-results">
|
<div class="col-span-6 sm:col-span-3 overflow-x-auto shadow-md sm:rounded-lg" id="search-results">
|
||||||
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
<tbody id="search-results-tbody">
|
<tbody id="search-results-tbody">
|
||||||
|
@ -38,9 +35,7 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="role" class="mb-2 block text-sm font-medium text-gray-900 dark:text-white">Select an option</label >
|
<label for="role" class="mb-2 block text-sm font-medium text-gray-900 dark:text-white">Select an option</label >
|
||||||
<select id="role" name="role" 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">
|
<select id="role" name="role" 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">
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<nav class="flex mt-5 mb-3" aria-label="Breadcrumb">
|
||||||
|
<ol class="inline-flex items-center space-x-1 md:space-x-3 ml-5">
|
||||||
|
{% for breadcrumb in breadcrumbs %}
|
||||||
|
<li class="inline-flex items-center">
|
||||||
|
<a href="{{ breadcrumb.url }}" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600 dark:text-gray-400 dark:hover:text-white">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<!--svg for all types of breadcrumb-->
|
||||||
|
{% if breadcrumb.type == "MyBookList" or breadcrumb.type == "AuthorBookList" %}
|
||||||
|
<svg aria-hidden="true" class="flex-shrink-0 w-4 h-4 mr-2 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"></path></svg>
|
||||||
|
{% else %}
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-4 h-4 mr-2 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /> </svg>
|
||||||
|
{% endif %}
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
{{ breadcrumb.label }}
|
||||||
|
</a>
|
||||||
|
<svg aria-hidden="true" class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path> </svg>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
|
@ -18,13 +18,8 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
||||||
<!-- prettier-ignore -->
|
{% include 'book/breadcrumbs_navigation.html'%}
|
||||||
<div class="flex p-2">
|
<h1 class="text-l font-extrabold dark:text-white ml-4">Collections page</h1>
|
||||||
<div>
|
|
||||||
<h1 class="text-l font-extrabold dark:text-white ml-4"> {{ book.owner.username }} </h1>
|
|
||||||
<h1 class="text-2xl font-extrabold dark:text-white ml-4">{{ book.label }}</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
||||||
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
||||||
|
@ -43,16 +38,11 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="myTabContent">
|
<div id="myTabContent">
|
||||||
<div
|
<!-- prettier-ignore -->
|
||||||
class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800"
|
<div class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="files" role="tabpanel" aria-labelledby="files-tab">
|
||||||
id="files"
|
<dl class="w-md md:w-full text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700">
|
||||||
role="tabpanel"
|
|
||||||
aria-labelledby="files-tab">
|
|
||||||
<dl
|
|
||||||
class="w-md md:w-full text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700">
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for collection in book.versions[-1].children_collections if not collection.is_root and not collection.is_deleted %}
|
{% for collection in book.versions[-1].children_collections if not collection.is_root and not collection.is_deleted %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<a href="{{url_for('book.sub_collection_view',book_id=book.id,collection_id=collection.id)}}" >
|
<a href="{{url_for('book.sub_collection_view',book_id=book.id,collection_id=collection.id)}}" >
|
||||||
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||||
|
@ -74,7 +64,6 @@
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</a >
|
</a >
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,14 +15,10 @@
|
||||||
|
|
||||||
{% for book in books %}
|
{% for book in books %}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<dl
|
<dl class=" bg-white dark:bg-gray-900 max-w-full p-5 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||||
class=" bg-white dark:bg-gray-900 max-w-full p-5 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
<a class="flex flex-col pb-2" href="{{url_for('book.collection_view',book_id=book.id)}}">
|
||||||
<a
|
|
||||||
class="flex flex-col pb-2"
|
|
||||||
href="{{url_for('book.collection_view',book_id=book.id)}}">
|
|
||||||
<dt class="mb-2">{{book.owner.username}}/{{book.label}}</dt>
|
<dt class="mb-2">{{book.owner.username}}/{{book.label}}</dt>
|
||||||
<dd
|
<dd class="flex flex-col md:flex-row text-lg font-semibold text-gray-500 md:text-lg dark:text-gray-400">
|
||||||
class="flex flex-col md:flex-row text-lg font-semibold text-gray-500 md:text-lg dark:text-gray-400">
|
|
||||||
{% if book.versions %}
|
{% if book.versions %}
|
||||||
<p>
|
<p>
|
||||||
Last updated on {{book.versions[-1].updated_at.strftime('%B %d, %Y')}}
|
Last updated on {{book.versions[-1].updated_at.strftime('%B %d, %Y')}}
|
||||||
|
@ -30,48 +26,15 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="flex ml-auto align-center justify-center space-x-3">
|
<div class="flex ml-auto align-center justify-center space-x-3">
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 22 22"
|
|
||||||
stroke-width="1"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-4 h-4 inline-flex mr-1">
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
|
|
||||||
</svg>
|
|
||||||
<p>{{ book.stars|length }}</p>
|
<p>{{ book.stars|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 22 22"
|
|
||||||
stroke-width="1"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-4 h-4 inline-flex mr-1">
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" />
|
|
||||||
</svg>
|
|
||||||
<p>55</p>
|
<p>55</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 22 22"
|
|
||||||
stroke-width="1"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="w-4 h-4 inline-flex mr-1">
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
|
|
||||||
</svg>
|
|
||||||
<p>55</p>
|
<p>55</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,6 +42,60 @@
|
||||||
</a>
|
</a>
|
||||||
</dl>
|
</dl>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
{% if page.pages > 1 %}
|
||||||
|
<div class="container content-center mt-3 flex bg-white dark:bg-gray-800">
|
||||||
|
<nav aria-label="Page navigation example" class="mx-auto">
|
||||||
|
<ul class="inline-flex items-center -space-x-px">
|
||||||
|
<li>
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<a href="{{ url_for('book.my_books') }}?page=1&q={{page.query}}" class="block px-3 py-2 ml-0 leading-tight text-gray-500 bg-white border border-gray-300 rounded-l-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||||
|
<span class="sr-only">First</span>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M15.79 14.77a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L11.832 10l3.938 3.71a.75.75 0 01.02 1.06zm-6 0a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L5.832 10l3.938 3.71a.75.75 0 01.02 1.06z" clip-rule="evenodd" /> </svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<a href="{{ url_for('book.my_books') }}?page={{page.page-1 if page.page > 1 else 1}}&q={{page.query}}" class="block px-3 py-2 ml-0 leading-tight text-gray-500 bg-white border border-gray-300 rounded-l-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||||
|
<span class="sr-only">Previous</span>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" /> </svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
{% for p in page.pages_for_links %}
|
||||||
|
<li>
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
{% if p == page.page %}
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<a href="{{ url_for('book.my_books') }}?page={{p}}&q={{page.query}}" aria-current="page" class="z-10 px-3 py-2 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white">{{p}}</a>
|
||||||
|
{% else %}
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<a href="{{ url_for('book.my_books') }}?page={{p}}&q={{page.query}}" class="px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">{{p}}</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<a href="{{ url_for('book.my_books') }}?page={{page.page+1 if page.page < page.pages else page.pages}}&q={{page.query}}" class="block px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 rounded-r-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<span class="sr-only">Next</span>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> </svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<a href="{{ url_for('book.my_books') }}?page={{page.pages}}&q={{page.query}}" class="block px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 rounded-r-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<span class="sr-only">Last</span>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"> <path fill-rule="evenodd" d="M10.21 14.77a.75.75 0 01.02-1.06L14.168 10 10.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> <path fill-rule="evenodd" d="M4.21 14.77a.75.75 0 01.02-1.06L8.168 10 4.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" /> </svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% include 'user/add.html' %}
|
{% include 'user/add.html' %}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
|
|
|
@ -2,19 +2,11 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
||||||
|
{% include 'book/breadcrumbs_navigation.html'%}
|
||||||
|
<h1 class="text-l font-extrabold dark:text-white ml-4">
|
||||||
|
Interpretations page
|
||||||
|
</h1>
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<div class="flex p-2">
|
|
||||||
<div>
|
|
||||||
<h1 class="text-l font-extrabold dark:text-white ml-4">
|
|
||||||
{{ book.owner.username }}/{{ book.label }}
|
|
||||||
</h1>
|
|
||||||
<h1 class="text-2xl font-extrabold dark:text-white ml-4">
|
|
||||||
{{collection.label}} {% if sub_collection %}/ {{sub_collection.label}} {% endif %} /{{section.label}}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- prettier-ignore -->
|
|
||||||
|
|
||||||
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
||||||
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
||||||
<li class="mr-2" role="presentation">
|
<li class="mr-2" role="presentation">
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
{% if book.owner.id == current_user.id %}
|
{% if book.owner.id == current_user.id %}
|
||||||
<!-- show edit collection btn on rightside bar -->
|
<!-- show edit collection btn on rightside bar -->
|
||||||
{% set show_edit_collection = True %}
|
{% set show_edit_collection = True %}
|
||||||
|
@ -19,24 +18,21 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
||||||
<!-- prettier-ignore -->
|
{% include 'book/breadcrumbs_navigation.html'%}
|
||||||
<div class="flex p-2">
|
<h1 class="text-l font-extrabold dark:text-white ml-4">Sections page</h1>
|
||||||
<div>
|
|
||||||
<h1 class="text-l font-extrabold dark:text-white ml-4"> {{ book.owner.username }}/{{ book.label }} </h1>
|
|
||||||
<h1 class="text-2xl font-extrabold dark:text-white ml-4">{{collection.label}}{% if sub_collection %}/ {{sub_collection.label}} {% endif %} </h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- prettier-ignore -->
|
|
||||||
|
|
||||||
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
||||||
<li class="mr-2" role="presentation">
|
<li class="mr-2" role="presentation">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<button class="flex items-center space-x-2 p-4 border-b-2 rounded-t-lg" id="files-tab" data-tabs-target="#files" type="button" role="tab" aria-controls="files" aria-selected="false">
|
<button class="flex items-center space-x-2 p-4 border-b-2 rounded-t-lg" id="files-tab" data-tabs-target="#files" type="button" role="tab" aria-controls="files" aria-selected="false">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m5.231 13.481L15 17.25m-4.5-15H5.625c-.621 0-1.125.504-1.125 1.125v16.5c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9zm3.75 11.625a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" /> </svg>
|
<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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m5.231 13.481L15 17.25m-4.5-15H5.625c-.621 0-1.125.504-1.125 1.125v16.5c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9zm3.75 11.625a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" /> </svg>
|
||||||
<span>Files</span>
|
<span>Files</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="mr-2" role="presentation">
|
<li class="mr-2" role="presentation">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<button class="flex items-center space-x-2 p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300" id="about-tab" data-tabs-target="#about" type="button" role="tab" aria-controls="about" aria-selected="false">
|
<button class="flex items-center space-x-2 p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300" id="about-tab" data-tabs-target="#about" type="button" role="tab" aria-controls="about" aria-selected="false">
|
||||||
<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="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 01-2.555-.337A5.972 5.972 0 015.41 20.97a5.969 5.969 0 01-.474-.065 4.48 4.48 0 00.978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25z" /> </svg>
|
<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="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 01-2.555-.337A5.972 5.972 0 015.41 20.97a5.969 5.969 0 01-.474-.065 4.48 4.48 0 00.978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25z" /> </svg>
|
||||||
<span>About</span>
|
<span>About</span>
|
||||||
|
@ -46,13 +42,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="myTabContent">
|
<div id="myTabContent">
|
||||||
<div
|
<!-- prettier-ignore -->
|
||||||
class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800"
|
<div class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="files" role="tabpanel" aria-labelledby="files-tab">
|
||||||
id="files"
|
<dl class="w-md md:w-full text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700">
|
||||||
role="tabpanel"
|
|
||||||
aria-labelledby="files-tab">
|
|
||||||
<dl
|
|
||||||
class="w-md md:w-full text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700">
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for section in sections %}
|
{% for section in sections %}
|
||||||
|
|
||||||
|
@ -72,7 +64,6 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /></svg>
|
||||||
<p>55</p>
|
<p>55</p>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /></svg>
|
||||||
<p>55</p>
|
<p>55</p>
|
||||||
|
@ -82,15 +73,10 @@
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="about" role="tabpanel" aria-labelledby="about-tab">
|
||||||
class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800"
|
|
||||||
id="about"
|
|
||||||
role="tabpanel"
|
|
||||||
aria-labelledby="about-tab">
|
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-400">This is about</p>
|
<p class="text-sm text-gray-500 dark:text-gray-400">This is about</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,24 +22,23 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
<div class="relative overflow-x-auto shadow-md sm:rounded-lg mt-5 md:mr-64">
|
||||||
<!-- prettier-ignore -->
|
{% include 'book/breadcrumbs_navigation.html'%}
|
||||||
<div class="flex p-2">
|
<h1 class="text-l font-extrabold dark:text-white ml-4">
|
||||||
<div>
|
Sub collections page
|
||||||
<h1 class="text-l font-extrabold dark:text-white ml-4"> {{ book.owner.username }}/{{ book.label }} </h1>
|
</h1>
|
||||||
<h1 class="text-2xl font-extrabold dark:text-white ml-4">{{collection.label}}</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- prettier-ignore -->
|
|
||||||
|
|
||||||
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
<div class="mb-1 border-b border-gray-200 dark:border-gray-700">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
<ul class="flex flex-wrap -mb-px text-sm font-medium text-center" id="myTab" data-tabs-toggle="#myTabContent" role="tablist">
|
||||||
<li class="mr-2" role="presentation">
|
<li class="mr-2" role="presentation">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<button class="flex items-center space-x-2 p-4 border-b-2 rounded-t-lg" id="files-tab" data-tabs-target="#files" type="button" role="tab" aria-controls="files" aria-selected="false">
|
<button class="flex items-center space-x-2 p-4 border-b-2 rounded-t-lg" id="files-tab" data-tabs-target="#files" type="button" role="tab" aria-controls="files" aria-selected="false">
|
||||||
<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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m5.231 13.481L15 17.25m-4.5-15H5.625c-.621 0-1.125.504-1.125 1.125v16.5c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9zm3.75 11.625a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" /> </svg>
|
<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="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m5.231 13.481L15 17.25m-4.5-15H5.625c-.621 0-1.125.504-1.125 1.125v16.5c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9zm3.75 11.625a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" /> </svg>
|
||||||
<span>Files</span>
|
<span>Files</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li class="mr-2" role="presentation">
|
<li class="mr-2" role="presentation">
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<button class="flex items-center space-x-2 p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300" id="about-tab" data-tabs-target="#about" type="button" role="tab" aria-controls="about" aria-selected="false">
|
<button class="flex items-center space-x-2 p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300" id="about-tab" data-tabs-target="#about" type="button" role="tab" aria-controls="about" aria-selected="false">
|
||||||
<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="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 01-2.555-.337A5.972 5.972 0 015.41 20.97a5.969 5.969 0 01-.474-.065 4.48 4.48 0 00.978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25z" /> </svg>
|
<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="M8.625 12a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H8.25m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0H12m4.125 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 01-2.555-.337A5.972 5.972 0 015.41 20.97a5.969 5.969 0 01-.474-.065 4.48 4.48 0 00.978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25z" /> </svg>
|
||||||
<span>About</span>
|
<span>About</span>
|
||||||
|
@ -49,22 +48,17 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="myTabContent">
|
<div id="myTabContent">
|
||||||
<div
|
<!-- prettier-ignore -->
|
||||||
class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800"
|
<div class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="files" role="tabpanel" aria-labelledby="files-tab">
|
||||||
id="files"
|
|
||||||
role="tabpanel"
|
|
||||||
aria-labelledby="files-tab">
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<dl class="w-md md:w-full text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700">
|
<dl class="w-md md:w-full text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% for sub_collection in collection.children %}
|
{% for sub_collection in collection.children %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<a href="{{url_for('book.section_view',book_id=book.id,collection_id=collection.id,sub_collection_id=sub_collection.id)}}">
|
<a href="{{url_for('book.section_view',book_id=book.id,collection_id=collection.id,sub_collection_id=sub_collection.id)}}">
|
||||||
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
<dl class="bg-white dark:bg-gray-900 max-w-full p-3 text-gray-900 divide-y divide-gray-200 dark:text-white dark:divide-gray-700 m-3 border-2 border-gray-200 border-solid rounded-lg dark:border-gray-700">
|
||||||
<div class="flex flex-col pb-3 p-3 w-full">
|
<div class="flex flex-col pb-3 p-3 w-full">
|
||||||
<dt
|
<dt class="flex w-full mb-1 text-gray-500 md:text-lg dark:text-gray-400 flex-col">
|
||||||
class="flex w-full mb-1 text-gray-500 md:text-lg dark:text-gray-400 flex-col">
|
|
||||||
<p>{{ sub_collection.label }}</p>
|
<p>{{ sub_collection.label }}</p>
|
||||||
<div class="ml-auto">
|
<div class="ml-auto">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
|
@ -80,17 +74,13 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<!-- prettier-ignore -->
|
||||||
class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800"
|
<div class="hidden p-4 rounded-lg bg-gray-50 dark:bg-gray-800" id="about" role="tabpanel" aria-labelledby="about-tab">
|
||||||
id="about"
|
|
||||||
role="tabpanel"
|
|
||||||
aria-labelledby="about-tab">
|
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
This is about of {{collection.about}}
|
This is about of {{collection.about}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<h1 class="text-l font-extrabold dark:text-white my-2">{{section.path}}</h1>
|
<h1 class="text-l font-extrabold dark:text-white my-2">{{section.path}}</h1>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<a type="button" href="{{ url_for('book.get_all') }}" class="mt-4 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"> Explore all sections... <svg aria-hidden="true" class="w-5 h-5 ml-2 -mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg> </a>
|
<a type="button" href="#" class="mt-4 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"> Explore all sections... <svg aria-hidden="true" class="w-5 h-5 ml-2 -mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg> </a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -35,17 +35,8 @@
|
||||||
<a
|
<a
|
||||||
href="{{ url_for('user.get_all') }}"
|
href="{{ url_for('user.get_all') }}"
|
||||||
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
|
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
|
||||||
<svg
|
<!-- prettier-ignore -->
|
||||||
aria-hidden="true"
|
<svg aria-hidden="true" class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"></path> </svg>
|
||||||
class="flex-shrink-0 w-6 h-6 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white"
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
|
|
||||||
clip-rule="evenodd"></path>
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 ml-3 whitespace-nowrap">Users</span>
|
<span class="flex-1 ml-3 whitespace-nowrap">Users</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -8,7 +8,7 @@ from flask import (
|
||||||
)
|
)
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
|
|
||||||
from app.controllers import create_pagination
|
from app.controllers import create_pagination, create_breadcrumbs
|
||||||
from app import models as m, db, forms as f
|
from app import models as m, db, forms as f
|
||||||
from app.logger import log
|
from app.logger import log
|
||||||
|
|
||||||
|
@ -101,12 +101,15 @@ def edit(book_id: int):
|
||||||
@bp.route("/<int:book_id>/collections", methods=["GET"])
|
@bp.route("/<int:book_id>/collections", methods=["GET"])
|
||||||
def collection_view(book_id: int):
|
def collection_view(book_id: int):
|
||||||
book = db.session.get(m.Book, book_id)
|
book = db.session.get(m.Book, book_id)
|
||||||
|
breadcrumbs = create_breadcrumbs(book_id=book_id, collection_path=())
|
||||||
if not book or book.is_deleted:
|
if not book or book.is_deleted:
|
||||||
log(log.WARNING, "Book with id [%s] not found", book_id)
|
log(log.WARNING, "Book with id [%s] not found", book_id)
|
||||||
flash("Book not found", "danger")
|
flash("Book not found", "danger")
|
||||||
return redirect(url_for("book.my_books"))
|
return redirect(url_for("book.my_books"))
|
||||||
else:
|
else:
|
||||||
return render_template("book/collection_view.html", book=book)
|
return render_template(
|
||||||
|
"book/collection_view.html", book=book, breadcrumbs=breadcrumbs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/<int:book_id>/<int:collection_id>/subcollections", methods=["GET"])
|
@bp.route("/<int:book_id>/<int:collection_id>/subcollections", methods=["GET"])
|
||||||
|
@ -116,19 +119,22 @@ def sub_collection_view(book_id: int, collection_id: int):
|
||||||
log(log.WARNING, "Book with id [%s] not found", book_id)
|
log(log.WARNING, "Book with id [%s] not found", book_id)
|
||||||
flash("Book not found", "danger")
|
flash("Book not found", "danger")
|
||||||
return redirect(url_for("book.my_books"))
|
return redirect(url_for("book.my_books"))
|
||||||
|
|
||||||
collection: m.Collection = db.session.get(m.Collection, collection_id)
|
collection: m.Collection = db.session.get(m.Collection, collection_id)
|
||||||
if not collection or collection.is_deleted:
|
if not collection or collection.is_deleted:
|
||||||
log(log.WARNING, "Collection with id [%s] not found", collection_id)
|
log(log.WARNING, "Collection with id [%s] not found", collection_id)
|
||||||
flash("Collection not found", "danger")
|
flash("Collection not found", "danger")
|
||||||
return redirect(url_for("book.collection_view", book_id=book_id))
|
return redirect(url_for("book.collection_view", book_id=book_id))
|
||||||
|
breadcrumbs = create_breadcrumbs(book_id=book_id, collection_path=(collection.id,))
|
||||||
if collection.is_leaf:
|
if collection.is_leaf:
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for("book.section_view", book_id=book.id, collection_id=collection.id)
|
url_for("book.section_view", book_id=book.id, collection_id=collection.id)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return render_template(
|
return render_template(
|
||||||
"book/sub_collection_view.html", book=book, collection=collection
|
"book/sub_collection_view.html",
|
||||||
|
book=book,
|
||||||
|
collection=collection,
|
||||||
|
breadcrumbs=breadcrumbs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,12 +177,21 @@ def section_view(
|
||||||
else:
|
else:
|
||||||
sections = collection.sections
|
sections = collection.sections
|
||||||
|
|
||||||
|
breadcrumbs = create_breadcrumbs(
|
||||||
|
book_id=book_id,
|
||||||
|
collection_path=(
|
||||||
|
collection_id,
|
||||||
|
sub_collection_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"book/section_view.html",
|
"book/section_view.html",
|
||||||
book=book,
|
book=book,
|
||||||
collection=collection,
|
collection=collection,
|
||||||
sections=sections,
|
sections=sections,
|
||||||
sub_collection=sub_collection,
|
sub_collection=sub_collection,
|
||||||
|
breadcrumbs=breadcrumbs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -232,12 +247,21 @@ def interpretation_view(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
breadcrumbs = create_breadcrumbs(
|
||||||
|
book_id=book_id,
|
||||||
|
collection_path=(
|
||||||
|
collection_id,
|
||||||
|
sub_collection_id,
|
||||||
|
),
|
||||||
|
section_id=section_id,
|
||||||
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"book/interpretation_view.html",
|
"book/interpretation_view.html",
|
||||||
book=book,
|
book=book,
|
||||||
collection=collection,
|
collection=collection,
|
||||||
sub_collection=sub_collection if sub_collection_id else None,
|
sub_collection=sub_collection if sub_collection_id else None,
|
||||||
section=section,
|
section=section,
|
||||||
|
breadcrumbs=breadcrumbs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
from flask.testing import FlaskCliRunner
|
||||||
|
from app.controllers import create_breadcrumbs
|
||||||
|
from app import models as m, db
|
||||||
|
|
||||||
|
|
||||||
|
def test_breadcrumbs(runner: FlaskCliRunner, app):
|
||||||
|
runner.invoke(args=["db-populate"])
|
||||||
|
with app.app_context(), app.test_request_context():
|
||||||
|
res = create_breadcrumbs(1, (1,), 1)
|
||||||
|
assert len(res) == 4
|
||||||
|
book: m.Book = db.session.get(m.Book, 1)
|
||||||
|
assert book
|
||||||
|
assert book.owner.username in res[0].label
|
||||||
|
assert res[1].label == book.label
|
||||||
|
with app.app_context(), app.test_request_context():
|
||||||
|
res = create_breadcrumbs(1, (), 1)
|
||||||
|
assert res
|
||||||
|
assert len(res) == 2
|
Loading…
Reference in New Issue