Consistent hero-tabs navigation #244

Merged
Oleg-Komarov merged 4 commits from hero-tabs into main 2024-09-03 11:55:35 +02:00
7 changed files with 74 additions and 55 deletions

View File

@ -51,29 +51,7 @@
{% block hero_tabs %}
<nav class="d-flex flex-column-reverse flex-md-row">
<div class="hero-tabs">
<a href="{{ extension.get_absolute_url }}" class="{% if extension.get_absolute_url == request.get_full_path %}is-active{% endif %}">
{% trans "About" %}
</a>
{% if latest.release_notes %}
<a href="{{ extension.get_absolute_url }}#new">
{% trans "What's New" %}
</a>
{% endif %}
{% if latest.permissions_with_reasons %}
<a href="{{ extension.get_absolute_url }}#permissions">
{% trans "Permissions" %}
</a>
{% endif %}
{% if extension.is_approved %}
<a href="{{ extension.get_ratings_url }}" class="{% if '/reviews/' in request.get_full_path %}is-active{% endif %}">
{% trans "Reviews" %}
</a>
{% endif %}
{% if extension.latest_version != None %}
<a href="{{ extension.get_versions_url }}" class="{% if '/versions/' in request.get_full_path %}is-active{% endif %}">
{% trans "Version History" %}
</a>
{% endif %}
{% include "extensions/components/hero_tabs.html" with extension=extension %}
</div>
<div class="btn-row hero-tabs-admin mb-3 mb-md-0">
{% if is_maintainer %}

View File

@ -0,0 +1,6 @@
{% load extensions %}
{% get_hero_tabs extension as hero_tabs %}
{% for tab in hero_tabs %}
<a href="{{ tab.href }}" class="{% if tab.is_active %}is-active{% endif %}">{{ tab.label }}</a>
{% endfor %}

View File

@ -22,7 +22,6 @@
<div class="row ext-version-history pb-3">
<div class="col">
{% for version in object_list %}
{% if version.is_listed or is_maintainer %}
<details {% if forloop.counter == 1 %}open{% endif %} id="v{{ version.version|slugify }}">
<summary>
{{ version.version }}
@ -97,7 +96,6 @@
{% endfor %}
</div>
</div>
{% if is_maintainer %}
<div class="dl-row">
<div class="dl-col">
<dt>Status</dt>
@ -105,10 +103,19 @@
<dd>{% include "common/components/status.html" with object=version.files.first %}</dd>
</div>
</div>
{% endif %}
</section>
<div class="btn-col">
{% if not is_maintainer and not extension.is_approved %}
<div class="card p-3 mt-3 ext-detail-download-danger">
<h3>Caution</h3>
pablovazquez marked this conversation as resolved
Review

Not sure how is this related to the hero tabs?

Not sure how is this related to the hero tabs?
Review

It relates to this part:

This commit also opens the "Version History" page for everyone

and the caution card is needed because if we decide to show "Version History" to everyone, we should the same warning as on the approval queue detail page.

Otherwise we should add more complicated checks to "Version History" display condition, and I think it's simpler and more useful to always show it.

It relates to this part: > This commit also opens the "Version History" page for everyone and the caution card is needed because if we decide to show "Version History" to everyone, we should the same warning as on the approval queue detail page. Otherwise we should add more complicated checks to "Version History" display condition, and I think it's simpler and more useful to always show it.
<p>
This extension has not been reviewed yet.<br>
<strong>Try at your own risk.</strong>
</p>
</div>
{% endif %}
{% with download_list=version.get_download_list %}
{% for download_item in download_list %}
<a href="{{ download_item.url }}" download="{{ download_item.name }}" class="btn btn-primary btn-block d-flex justify-content-between text-start">
@ -139,7 +146,6 @@
</div>
</div>
</details>
{% endif %}
{% endfor %}
</div>

View File

@ -1,4 +1,5 @@
from django.template import Library
from django.utils.translation import gettext_lazy as _
import extensions.models
@ -17,3 +18,55 @@ def can_rate(context, extension: extensions.models.Extension) -> bool:
"""Return True if current user can rate a given extension."""
request = context.get('request')
return extension.can_rate(request.user)
@register.simple_tag(takes_context=True)
def get_hero_tabs(context, extension: extensions.models.Extension):
request = context.get('request')
extension_absolute_url = extension.get_absolute_url()
extension_review_url = extension.get_review_url()
latest_version = extension.latest_version
hero_tabs = [
{
'condition': extension.is_listed,
'href': extension_absolute_url,
'is_active': request.path == extension_absolute_url,
'label': _("About"),
},
{
'condition': extension.is_listed and latest_version and latest_version.release_notes,
'href': extension_absolute_url + '#new',
'label': _("What's New"),
},
{
'condition': (
extension.is_listed and latest_version and latest_version.permissions_with_reasons
),
'href': extension_absolute_url + '#permissions',
'label': _("Permissions"),
},
{
'condition': extension.is_listed,
'href': extension.get_ratings_url(),
'is_active': '/reviews/' in request.path,
'label': _("Reviews"),
},
{
'condition': not extension.is_listed,
'href': extension_review_url + '#about',
'label': _("About"),
},
{
'condition': not extension.is_listed,
'href': extension_review_url + '#activity',
'label': _("Activity"),
},
{
'condition': latest_version,
'href': extension.get_versions_url(),
'is_active': '/versions/' in request.path,
'label': _("Version History"),
},
]
return filter(lambda t: t['condition'], hero_tabs)

View File

@ -8,7 +8,6 @@ from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormVi
from .mixins import (
ExtensionQuerysetMixin,
OwnsFileMixin,
MaintainedExtensionMixin,
DraftVersionMixin,
@ -25,13 +24,12 @@ from files.forms import FileForm
from files.models import File
class VersionsView(ExtensionQuerysetMixin, ListView):
class VersionsView(ListView):
model = Version
paginate_by = 15
def get_queryset(self):
self.extension_queryset = self.get_extension_queryset()
self.extension = get_object_or_404(self.extension_queryset, slug=self.kwargs['slug'])
self.extension = get_object_or_404(Extension, slug=self.kwargs['slug'])
return self.extension.versions.prefetch_related('files', 'platforms', 'permissions')
def get_context_data(self, **kwargs):

View File

@ -14,18 +14,6 @@ class OwnsFileMixin(UserPassesTestMixin):
return self.file.user == self.request.user
class ExtensionQuerysetMixin:
"""Add reusable methods to class-based views handling Extensions."""
def get_extension_queryset(self):
"""Return queryset with unlisted add-ons for logged in users under certain conditions."""
if self.request.user.is_staff:
return Extension.objects.all()
if self.request.user.is_authenticated:
return Extension.objects.listed_or_authored_by(self.request.user)
return Extension.objects.listed
class MaintainedExtensionMixin:
"""Fetch an extension by slug if current user is a maintainer."""

View File

@ -1,5 +1,5 @@
{% extends "extensions/detail.html" %}
{% load common extensions filters i18n humanize static %}
{% load common filters i18n humanize static %}
{% block page_title %}Review: {{ extension.name }}{% endblock page_title %}
@ -15,17 +15,7 @@
{% block hero_tabs %}
<div class="d-flex flex-column-reverse flex-md-row">
<div class="hero-tabs">
<a href="#about">
{% trans "About" %}
</a>
<a href="#activity">
{% trans "Activity" %}
</a>
{% if extension.latest_version != None %}
<a href="{{ extension.get_versions_url }}" class="{% if '/versions/' in request.get_full_path %}is-active{% endif %}">
{% trans "Version History" %}
</a>
{% endif %}
{% include "extensions/components/hero_tabs.html" with extension=extension %}
</div>
<div class="btn-row hero-tabs-admin mb-3 mb-md-0">
{% if is_maintainer %}