forked from enviPath/enviPy
[Feature] Modern UI roll out (#236)
This PR moves all the collection pages into the new UI in a rough push. I did not put the same amount of care into these as into search, index, and predict. ## Major changes - All modals are now migrated to a state based alpine.js implementation. - jQuery is no longer present in the base layout; ajax is replace by native fetch api - most of the pps.js is now obsolte (as I understand it; the code is not referenced any more @jebus please double check) - in-memory pagination for large result lists (set to 50; we can make that configurable later; performance degrades at around 1k) stukk a bit rough tracked in #235 ## Minor things - Sarch and index also use alpine now - The loading spinner is now CSS animated (not sure if it currently gets correctly called) ## Not done - Ihave not even cheked the admin pages. Not sure If these need migrations - The temporary migration pages still use the old template. Not sure what is supposed to happen with those? @jebus ## What I did to test - opend all pages in browse, and user ; plus all pages reachable from there. - Interacted and tested the functionality of each modal superfically with exception of the API key modal (no functional test). --- This PR is massive sorry for that; just did not want to push half-brokenn state. @jebus @liambrydon I would be glad if you could click around and try to break it :) Finally closes #133 Co-authored-by: Tim Lorsbach <tim@lorsba.ch> Reviewed-on: enviPath/enviPy#236 Co-authored-by: Tobias O <tobias.olenyi@envipath.com> Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
This commit is contained in:
@ -1,28 +1,32 @@
|
||||
{% extends "framework.html" %}
|
||||
{% extends "framework_modern.html" %}
|
||||
{% load static %}
|
||||
{% block content %}
|
||||
|
||||
{% if object_type != 'package' %}
|
||||
<div>
|
||||
<div id="load-all-error" style="display: none;">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<span
|
||||
class="glyphicon glyphicon-exclamation-sign"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span class="sr-only">Error:</span>
|
||||
Getting objects failed!
|
||||
</div>
|
||||
</div>
|
||||
{# Serialize objects data for Alpine pagination #}
|
||||
{# prettier-ignore-start #}
|
||||
{# FIXME: This is a hack to get the objects data into the JavaScript code. #}
|
||||
<script>
|
||||
window.reviewedObjects = [
|
||||
{% for obj in reviewed_objects %}
|
||||
{ "name": "{{ obj.name|escapejs }}", "url": "{{ obj.url }}" }{% if not forloop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
];
|
||||
window.unreviewedObjects = [
|
||||
{% for obj in unreviewed_objects %}
|
||||
{ "name": "{{ obj.name|escapejs }}", "url": "{{ obj.url }}" }{% if not forloop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
];
|
||||
</script>
|
||||
{# prettier-ignore-end #}
|
||||
|
||||
{% if object_type != 'package' %}
|
||||
<div class="px-8 py-4">
|
||||
<input
|
||||
type="text"
|
||||
id="object-search"
|
||||
class="form-control"
|
||||
class="input input-bordered hidden w-full max-w-xs"
|
||||
placeholder="Search by name"
|
||||
style="display: none;"
|
||||
/>
|
||||
<p></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@ -56,423 +60,474 @@
|
||||
{% endif %}
|
||||
{% endblock action_modals %}
|
||||
|
||||
<div class="panel-group" id="reviewListAccordion">
|
||||
<div class="panel panel-default">
|
||||
<div
|
||||
class="panel-heading"
|
||||
id="headingPanel"
|
||||
style="font-size:2rem;height: 46px"
|
||||
>
|
||||
{% if object_type == 'package' %}
|
||||
Packages
|
||||
{% elif object_type == 'compound' %}
|
||||
Compounds
|
||||
{% elif object_type == 'structure' %}
|
||||
Compound structures
|
||||
{% elif object_type == 'rule' %}
|
||||
Rules
|
||||
{% elif object_type == 'reaction' %}
|
||||
Reactions
|
||||
{% elif object_type == 'pathway' %}
|
||||
Pathways
|
||||
{% elif object_type == 'node' %}
|
||||
Nodes
|
||||
{% elif object_type == 'edge' %}
|
||||
Edges
|
||||
{% elif object_type == 'scenario' %}
|
||||
Scenarios
|
||||
{% elif object_type == 'model' %}
|
||||
Model
|
||||
{% elif object_type == 'setting' %}
|
||||
Settings
|
||||
{% elif object_type == 'user' %}
|
||||
Users
|
||||
{% elif object_type == 'group' %}
|
||||
Groups
|
||||
{% endif %}
|
||||
<div
|
||||
id="actionsButton"
|
||||
style="float: right;font-weight: normal;font-size: medium;position: relative; top: 50%; transform: translateY(-50%);z-index:100;display: none;"
|
||||
class="dropdown"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
class="dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
role="button"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
><span class="glyphicon glyphicon-wrench"></span> Actions
|
||||
<span class="caret"></span><span style="padding-right:1em"></span
|
||||
></a>
|
||||
<ul id="actionsList" class="dropdown-menu">
|
||||
{% block actions %}
|
||||
{% if object_type == 'package' %}
|
||||
{% include "actions/collections/package.html" %}
|
||||
{% elif object_type == 'compound' %}
|
||||
{% include "actions/collections/compound.html" %}
|
||||
{% elif object_type == 'structure' %}
|
||||
{% include "actions/collections/compound_structure.html" %}
|
||||
{% elif object_type == 'rule' %}
|
||||
{% include "actions/collections/rule.html" %}
|
||||
{% elif object_type == 'reaction' %}
|
||||
{% include "actions/collections/reaction.html" %}
|
||||
{% elif object_type == 'setting' %}
|
||||
{% include "actions/collections/setting.html" %}
|
||||
{% elif object_type == 'scenario' %}
|
||||
{% include "actions/collections/scenario.html" %}
|
||||
{% elif object_type == 'model' %}
|
||||
{% include "actions/collections/model.html" %}
|
||||
{% elif object_type == 'pathway' %}
|
||||
{% include "actions/collections/pathway.html" %}
|
||||
{% elif object_type == 'node' %}
|
||||
{% include "actions/collections/node.html" %}
|
||||
{% elif object_type == 'edge' %}
|
||||
{% include "actions/collections/edge.html" %}
|
||||
{% elif object_type == 'group' %}
|
||||
{% include "actions/collections/group.html" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</ul>
|
||||
<div class="px-8 py-4">
|
||||
<!-- Header Section -->
|
||||
<div class="card bg-base-100">
|
||||
<div class="card-body px-0 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="card-title text-2xl">
|
||||
{% if object_type == 'package' %}
|
||||
Packages
|
||||
{% elif object_type == 'compound' %}
|
||||
Compounds
|
||||
{% elif object_type == 'structure' %}
|
||||
Compound structures
|
||||
{% elif object_type == 'rule' %}
|
||||
Rules
|
||||
{% elif object_type == 'reaction' %}
|
||||
Reactions
|
||||
{% elif object_type == 'pathway' %}
|
||||
Pathways
|
||||
{% elif object_type == 'node' %}
|
||||
Nodes
|
||||
{% elif object_type == 'edge' %}
|
||||
Edges
|
||||
{% elif object_type == 'scenario' %}
|
||||
Scenarios
|
||||
{% elif object_type == 'model' %}
|
||||
Model
|
||||
{% elif object_type == 'setting' %}
|
||||
Settings
|
||||
{% elif object_type == 'user' %}
|
||||
Users
|
||||
{% elif object_type == 'group' %}
|
||||
Groups
|
||||
{% endif %}
|
||||
</h2>
|
||||
<div id="actionsButton" class="dropdown dropdown-end hidden">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost btn-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-wrench"
|
||||
>
|
||||
<path
|
||||
d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"
|
||||
/>
|
||||
</svg>
|
||||
Actions
|
||||
</div>
|
||||
<ul
|
||||
tabindex="-1"
|
||||
class="dropdown-content menu bg-base-100 rounded-box z-50 w-52 p-2"
|
||||
>
|
||||
{% block actions %}
|
||||
{% if object_type == 'package' %}
|
||||
{% include "actions/collections/package.html" %}
|
||||
{% elif object_type == 'compound' %}
|
||||
{% include "actions/collections/compound.html" %}
|
||||
{% elif object_type == 'structure' %}
|
||||
{% include "actions/collections/compound_structure.html" %}
|
||||
{% elif object_type == 'rule' %}
|
||||
{% include "actions/collections/rule.html" %}
|
||||
{% elif object_type == 'reaction' %}
|
||||
{% include "actions/collections/reaction.html" %}
|
||||
{% elif object_type == 'setting' %}
|
||||
{% include "actions/collections/setting.html" %}
|
||||
{% elif object_type == 'scenario' %}
|
||||
{% include "actions/collections/scenario.html" %}
|
||||
{% elif object_type == 'model' %}
|
||||
{% include "actions/collections/model.html" %}
|
||||
{% elif object_type == 'pathway' %}
|
||||
{% include "actions/collections/pathway.html" %}
|
||||
{% elif object_type == 'node' %}
|
||||
{% include "actions/collections/node.html" %}
|
||||
{% elif object_type == 'edge' %}
|
||||
{% include "actions/collections/edge.html" %}
|
||||
{% elif object_type == 'group' %}
|
||||
{% include "actions/collections/group.html" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<!-- Set Text above links -->
|
||||
{% if object_type == 'package' %}
|
||||
<p>
|
||||
A package contains pathways, rules, etc. and can reflect specific
|
||||
experimental conditions.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/packages"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'compound' %}
|
||||
<p>
|
||||
A compound stores the structure of a molecule and can include
|
||||
meta-information.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/compounds"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'structure' %}
|
||||
<p>
|
||||
The structures stored in this compound
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/compounds"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'rule' %}
|
||||
<p>
|
||||
A rule describes a biotransformation reaction template that is
|
||||
defined as SMIRKS.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/Rules"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'reaction' %}
|
||||
<p>
|
||||
A reaction is a specific biotransformation from educt compounds to
|
||||
product compounds.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/reactions"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'pathway' %}
|
||||
<p>
|
||||
A pathway displays the (predicted) biodegradation of a compound as
|
||||
graph.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/pathways"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'node' %}
|
||||
<p>
|
||||
Nodes represent the (predicted) compounds in a graph.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/nodes"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'edge' %}
|
||||
<p>
|
||||
Edges represent the links between Nodes in a graph
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/edges"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'scenario' %}
|
||||
<p>
|
||||
A scenario contains meta-information that can be attached to other
|
||||
data (compounds, rules, ..).
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/scenarios"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'model' %}
|
||||
<p>
|
||||
A model applies machine learning to limit the combinatorial
|
||||
explosion.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/relative_reasoning"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'setting' %}
|
||||
<p>
|
||||
A setting includes configuration parameters for pathway predictions.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/settings"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'user' %}
|
||||
<p>
|
||||
Register now to create own packages and to submit and manage your
|
||||
data.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/users"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'group' %}
|
||||
<p>
|
||||
Users can team up in groups to share packages.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/groups"
|
||||
role="button"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<!-- If theres nothing to show extend the text above -->
|
||||
{% if reviewed_objects and unreviewed_objects %}
|
||||
{% if reviewed_objects|length == 0 and unreviewed_objects|length == 0 %}
|
||||
<div class="mt-2">
|
||||
<!-- Set Text above links -->
|
||||
{% if object_type == 'package' %}
|
||||
<p>
|
||||
Nothing found. There are two possible reasons: <br /><br />1.
|
||||
There is no content yet.<br />2. You have no reading
|
||||
permissions.<br /><br />Please be sure you have at least reading
|
||||
permissions.
|
||||
A package contains pathways, rules, etc. and can reflect specific
|
||||
experimental conditions.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/packages"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'compound' %}
|
||||
<p>
|
||||
A compound stores the structure of a molecule and can include
|
||||
meta-information.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/compounds"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'structure' %}
|
||||
<p>
|
||||
The structures stored in this compound
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/compounds"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'rule' %}
|
||||
<p>
|
||||
A rule describes a biotransformation reaction template that is
|
||||
defined as SMIRKS.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/Rules"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'reaction' %}
|
||||
<p>
|
||||
A reaction is a specific biotransformation from educt compounds to
|
||||
product compounds.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/reactions"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'pathway' %}
|
||||
<p>
|
||||
A pathway displays the (predicted) biodegradation of a compound as
|
||||
graph.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/pathways"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'node' %}
|
||||
<p>
|
||||
Nodes represent the (predicted) compounds in a graph.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/nodes"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'edge' %}
|
||||
<p>
|
||||
Edges represent the links between Nodes in a graph
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/edges"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'scenario' %}
|
||||
<p>
|
||||
A scenario contains meta-information that can be attached to other
|
||||
data (compounds, rules, ..).
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/scenarios"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'model' %}
|
||||
<p>
|
||||
A model applies machine learning to limit the combinatorial
|
||||
explosion.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/relative_reasoning"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'setting' %}
|
||||
<p>
|
||||
A setting includes configuration parameters for pathway
|
||||
predictions.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/settings"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'user' %}
|
||||
<p>
|
||||
Register now to create own packages and to submit and manage your
|
||||
data.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/users"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% elif object_type == 'group' %}
|
||||
<p>
|
||||
Users can team up in groups to share packages.
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://wiki.envipath.org/index.php/groups"
|
||||
class="link link-primary"
|
||||
>Learn more >></a
|
||||
>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<!-- If theres nothing to show extend the text above -->
|
||||
{% if reviewed_objects and unreviewed_objects %}
|
||||
{% if reviewed_objects|length == 0 and unreviewed_objects|length == 0 %}
|
||||
<p class="mt-4">
|
||||
Nothing found. There are two possible reasons: <br /><br />1.
|
||||
There is no content yet.<br />2. You have no reading
|
||||
permissions.<br /><br />Please be sure you have at least reading
|
||||
permissions.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Lists Container - Full Width with Reviewed on Right -->
|
||||
<div class="w-full">
|
||||
{% if reviewed_objects %}
|
||||
{% if reviewed_objects|length > 0 %}
|
||||
<!-- Reviewed -->
|
||||
<div
|
||||
class="panel panel-default panel-heading list-group-item"
|
||||
style="background-color:silver"
|
||||
class="collapse-arrow bg-base-200 collapse order-2 w-full"
|
||||
x-data="paginatedList(window.reviewedObjects || [], { isReviewed: true, instanceId: 'reviewed' })"
|
||||
>
|
||||
<h4 class="panel-title">
|
||||
<a
|
||||
id="ReviewedLink"
|
||||
data-toggle="collapse"
|
||||
data-parent="#reviewListAccordion"
|
||||
href="#Reviewed"
|
||||
>Reviewed</a
|
||||
<input type="checkbox" checked />
|
||||
<div class="collapse-title text-xl font-medium">
|
||||
Reviewed
|
||||
<span
|
||||
class="badge badge-sm badge-neutral ml-2"
|
||||
x-text="totalItems"
|
||||
></span>
|
||||
</div>
|
||||
<div class="collapse-content w-full">
|
||||
<ul class="menu bg-base-100 rounded-box w-full">
|
||||
<template x-for="obj in paginatedItems" :key="obj.url">
|
||||
<li>
|
||||
<a :href="obj.url" class="hover:bg-base-200">
|
||||
<span x-text="obj.name"></span>
|
||||
<span
|
||||
class="tooltip tooltip-left ml-auto"
|
||||
data-tip="Reviewed"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-star"
|
||||
>
|
||||
<polygon
|
||||
points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<!-- Pagination Controls -->
|
||||
<div
|
||||
x-show="totalPages > 1"
|
||||
class="mt-4 flex items-center justify-between px-2"
|
||||
>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="Reviewed" class="panel-collapse in collapse">
|
||||
<div class="panel-body list-group-item" id="ReviewedContent">
|
||||
{% if object_type == 'package' %}
|
||||
{% for obj in reviewed_objects %}
|
||||
<a class="list-group-item" href="{{ obj.url }}"
|
||||
>{{ obj.name|safe }}
|
||||
<span
|
||||
class="glyphicon glyphicon-star"
|
||||
aria-hidden="true"
|
||||
style="float:right"
|
||||
data-toggle="tooltip"
|
||||
data-placement="top"
|
||||
title=""
|
||||
data-original-title="Reviewed"
|
||||
>
|
||||
</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for obj in reviewed_objects|slice:":50" %}
|
||||
<a class="list-group-item" href="{{ obj.url }}"
|
||||
>{{ obj.name|safe }}{# <i>({{ obj.package.name }})</i> #}
|
||||
<span
|
||||
class="glyphicon glyphicon-star"
|
||||
aria-hidden="true"
|
||||
style="float:right"
|
||||
data-toggle="tooltip"
|
||||
data-placement="top"
|
||||
title=""
|
||||
data-original-title="Reviewed"
|
||||
>
|
||||
</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<span class="text-base-content/70 text-sm">
|
||||
Showing <span x-text="showingStart"></span>-<span
|
||||
x-text="showingEnd"
|
||||
></span>
|
||||
of <span x-text="totalItems"></span>
|
||||
</span>
|
||||
<div class="join">
|
||||
<button
|
||||
class="join-item btn btn-sm"
|
||||
:disabled="currentPage === 1"
|
||||
@click="prevPage()"
|
||||
>
|
||||
«
|
||||
</button>
|
||||
<template x-for="item in pageNumbers" :key="item.key">
|
||||
<button
|
||||
class="join-item btn btn-sm"
|
||||
:class="{ 'btn-active': item.page === currentPage }"
|
||||
:disabled="item.isEllipsis"
|
||||
@click="!item.isEllipsis && goToPage(item.page)"
|
||||
x-text="item.page"
|
||||
></button>
|
||||
</template>
|
||||
<button
|
||||
class="join-item btn btn-sm"
|
||||
:disabled="currentPage === totalPages"
|
||||
@click="nextPage()"
|
||||
>
|
||||
»
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if unreviewed_objects %}
|
||||
<!-- Unreviewed -->
|
||||
<div
|
||||
class="panel panel-default panel-heading list-group-item"
|
||||
style="background-color:silver"
|
||||
class="collapse-arrow bg-base-200 collapse order-1 w-full"
|
||||
x-data="paginatedList(window.unreviewedObjects || [], { isReviewed: false, instanceId: 'unreviewed' })"
|
||||
>
|
||||
<h4 class="panel-title">
|
||||
<a
|
||||
id="UnreviewedLink"
|
||||
data-toggle="collapse"
|
||||
data-parent="#unReviewListAccordion"
|
||||
href="#Unreviewed"
|
||||
>Unreviewed</a
|
||||
<input
|
||||
type="checkbox"
|
||||
{% if reviewed_objects|length == 0 or object_type == 'package' %}checked{% endif %}
|
||||
/>
|
||||
<div class="collapse-title text-xl font-medium">
|
||||
Unreviewed
|
||||
<span
|
||||
class="badge badge-sm badge-neutral ml-2"
|
||||
x-text="totalItems"
|
||||
></span>
|
||||
</div>
|
||||
<div class="collapse-content w-full">
|
||||
<ul class="menu bg-base-100 rounded-box w-full">
|
||||
<template x-for="obj in paginatedItems" :key="obj.url">
|
||||
<li>
|
||||
<a
|
||||
:href="obj.url"
|
||||
class="hover:bg-base-200"
|
||||
x-text="obj.name"
|
||||
></a>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<!-- Pagination Controls -->
|
||||
<div
|
||||
x-show="totalPages > 1"
|
||||
class="mt-4 flex items-center justify-between px-2"
|
||||
>
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
id="Unreviewed"
|
||||
class="panel-collapse {% if reviewed_objects|length == 0 or object_type == 'package' %}in{% endif %} collapse"
|
||||
>
|
||||
<div class="panel-body list-group-item" id="UnreviewedContent">
|
||||
{% if object_type == 'package' %}
|
||||
{% for obj in unreviewed_objects %}
|
||||
<a class="list-group-item" href="{{ obj.url }}"
|
||||
>{{ obj.name|safe }}</a
|
||||
<span class="text-base-content/70 text-sm">
|
||||
Showing <span x-text="showingStart"></span>-<span
|
||||
x-text="showingEnd"
|
||||
></span>
|
||||
of <span x-text="totalItems"></span>
|
||||
</span>
|
||||
<div class="join">
|
||||
<button
|
||||
class="join-item btn btn-sm"
|
||||
:disabled="currentPage === 1"
|
||||
@click="prevPage()"
|
||||
>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for obj in unreviewed_objects|slice:":50" %}
|
||||
<a class="list-group-item" href="{{ obj.url }}"
|
||||
>{{ obj.name|safe }}</a
|
||||
«
|
||||
</button>
|
||||
<template x-for="item in pageNumbers" :key="item.key">
|
||||
<button
|
||||
class="join-item btn btn-sm"
|
||||
:class="{ 'btn-active': item.page === currentPage }"
|
||||
:disabled="item.isEllipsis"
|
||||
@click="!item.isEllipsis && goToPage(item.page)"
|
||||
x-text="item.page"
|
||||
></button>
|
||||
</template>
|
||||
<button
|
||||
class="join-item btn btn-sm"
|
||||
:disabled="currentPage === totalPages"
|
||||
@click="nextPage()"
|
||||
>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
»
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if objects %}
|
||||
<!-- Unreviewable objects such as User / Group / Setting -->
|
||||
<ul class="list-group">
|
||||
{% for obj in objects %}
|
||||
{% if object_type == 'user' %}
|
||||
<a class="list-group-item" href="{{ obj.url }}"
|
||||
>{{ obj.username|safe }}</a
|
||||
>
|
||||
{% else %}
|
||||
<a class="list-group-item" href="{{ obj.url }}"
|
||||
>{{ obj.name|safe }}</a
|
||||
>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
<style>
|
||||
.spinner-widget {
|
||||
position: fixed; /* stays in place on scroll */
|
||||
bottom: 20px; /* distance from bottom */
|
||||
right: 20px; /* distance from right */
|
||||
z-index: 9999; /* above most elements */
|
||||
width: 60px; /* adjust to gif size */
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.spinner-widget img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="load-all-loading" class="spinner-widget" style="display: none">
|
||||
<img
|
||||
id="loading-gif"
|
||||
src="{% static '/images/wait.gif' %}"
|
||||
alt="Loading..."
|
||||
/>
|
||||
</div>
|
||||
{% if objects %}
|
||||
<!-- Unreviewable objects such as User / Group / Setting -->
|
||||
<div class="card bg-base-100">
|
||||
<div class="card-body">
|
||||
<ul class="menu bg-base-200 rounded-box">
|
||||
{% for obj in objects %}
|
||||
{% if object_type == 'user' %}
|
||||
<li>
|
||||
<a href="{{ obj.url }}" class="hover:bg-base-300"
|
||||
>{{ obj.username }}</a
|
||||
>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a href="{{ obj.url }}" class="hover:bg-base-300"
|
||||
>{{ obj.name }}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{# prettier-ignore-start #}
|
||||
<script>
|
||||
$(function () {
|
||||
|
||||
$('#object-search').show();
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// Show actions button if there are actions
|
||||
const actionsButton = document.getElementById("actionsButton");
|
||||
const actionsList = actionsButton?.querySelector("ul");
|
||||
if (actionsList && actionsList.children.length > 0) {
|
||||
actionsButton?.classList.remove("hidden");
|
||||
}
|
||||
|
||||
{% if object_type != 'package' and object_type != 'user' and object_type != 'group' %}
|
||||
{% if reviewed_objects|length > 50 or unreviewed_objects|length > 50 %}
|
||||
$('#load-all-loading').show()
|
||||
|
||||
setTimeout(function () {
|
||||
$('#load-all-error').hide();
|
||||
|
||||
$.getJSON('?all=true', function (resp) {
|
||||
$('#ReviewedContent').empty();
|
||||
$('#UnreviewedContent').empty();
|
||||
|
||||
for (o in resp.objects) {
|
||||
obj = resp.objects[o];
|
||||
if (obj.reviewed) {
|
||||
$('#ReviewedContent').append('<a class="list-group-item" href="' + obj.url + '">' + obj.name + ' <span class="glyphicon glyphicon-star" aria-hidden="true" style="float:right" data-toggle="tooltip" data-placement="top" title="" data-original-title="Reviewed"></span></a>');
|
||||
} else {
|
||||
$('#UnreviewedContent').append('<a class="list-group-item" href="' + obj.url + '">' + obj.name + '</a>');
|
||||
}
|
||||
}
|
||||
|
||||
$('#load-all-loading').hide();
|
||||
$('#load-remaining').hide();
|
||||
}).fail(function (resp) {
|
||||
$('#load-all-loading').hide();
|
||||
$('#load-all-error').show();
|
||||
});
|
||||
|
||||
}, 2500);
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
$('#modal-form-delete-submit').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$('#modal-form-delete').submit();
|
||||
// Show search input and connect to Alpine pagination
|
||||
const objectSearch = document.getElementById("object-search");
|
||||
if (objectSearch) {
|
||||
objectSearch.classList.remove("hidden");
|
||||
objectSearch.addEventListener("input", function () {
|
||||
const query = this.value;
|
||||
// Dispatch search to all paginatedList components
|
||||
document
|
||||
.querySelectorAll('[x-data*="paginatedList"]')
|
||||
.forEach((el) => {
|
||||
if (el._x_dataStack && el._x_dataStack[0]) {
|
||||
el._x_dataStack[0].search(query);
|
||||
}
|
||||
});
|
||||
|
||||
$('#object-search').on('keyup', function () {
|
||||
let query = $(this).val().toLowerCase();
|
||||
$('a.list-group-item').each(function () {
|
||||
let text = $(this).text().toLowerCase();
|
||||
$(this).toggle(text.indexOf(query) !== -1);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{# prettier-ignore-end #}
|
||||
}
|
||||
|
||||
// Delete form submit handler
|
||||
const deleteSubmit = document.getElementById("modal-form-delete-submit");
|
||||
const deleteForm = document.getElementById("modal-form-delete");
|
||||
if (deleteSubmit && deleteForm) {
|
||||
deleteSubmit.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
deleteForm.submit();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock content %}
|
||||
|
||||
Reference in New Issue
Block a user