Unify package edit UI

This commit is contained in:
rubenwardy 2021-05-04 03:15:26 +01:00
parent 24e3b1505b
commit 1389cf450c
14 changed files with 223 additions and 103 deletions

@ -16,6 +16,42 @@
from flask import Blueprint
from app.models import User, Package, Permission
bp = Blueprint("packages", __name__)
def get_package_tabs(user: User, package: Package):
if package is None or not package.checkPerm(user, Permission.EDIT_PACKAGE):
return []
return [
{
"id": "edit",
"title": "Edit Details",
"url": package.getEditURL()
},
{
"id": "releases",
"title": "Releases",
"url": package.getReleaseListURL()
},
{
"id": "screenshots",
"title": "Screenshots",
"url": package.getEditScreenshotsURL()
},
{
"id": "maintainers",
"title": "Maintainers",
"url": package.getEditMaintainersURL()
},
{
"id": "remove",
"title": "Remove",
"url": package.getRemoveURL()
}
]
from . import packages, screenshots, releases, reviews

@ -32,7 +32,7 @@ from app.querybuilder import QueryBuilder
from app.rediscache import has_key, set_key
from app.tasks.importtasks import importRepoScreenshot, checkZipRelease
from app.utils import *
from . import bp
from . import bp, get_package_tabs
from ...logic.LogicError import LogicError
from ...logic.packages import do_edit_package
@ -339,7 +339,8 @@ def create_edit(author=None, name=None):
return render_template("packages/create_edit.html", package=package,
form=form, author=author, enable_wizard=enableWizard,
packages=package_query.all(),
mpackages=MetaPackage.query.order_by(db.asc(MetaPackage.name)).all())
mpackages=MetaPackage.query.order_by(db.asc(MetaPackage.name)).all(),
tabs=get_package_tabs(current_user, package), current_tab="edit")
@bp.route("/packages/<author>/<name>/state/", methods=["POST"])
@ -388,7 +389,8 @@ def move_to_state(package):
@is_package_page
def remove(package):
if request.method == "GET":
return render_template("packages/remove.html", package=package)
return render_template("packages/remove.html", package=package,
tabs=get_package_tabs(current_user, package), current_tab="remove")
if "delete" in request.form:
if not package.checkPerm(current_user, Permission.DELETE_PACKAGE):
@ -478,8 +480,8 @@ def edit_maintainers(package):
users = User.query.filter(User.rank >= UserRank.NEW_MEMBER).order_by(db.asc(User.username)).all()
return render_template("packages/edit_maintainers.html",
package=package, form=form, users=users)
return render_template("packages/edit_maintainers.html", package=package, form=form,
users=users, tabs=get_package_tabs(current_user, package), current_tab="maintainers")
@bp.route("/packages/<author>/<name>/remove-self-maintainer/", methods=["POST"])

@ -26,7 +26,15 @@ from app.logic.releases import do_create_vcs_release, LogicError, do_create_zip_
from app.rediscache import has_key, set_key, make_download_key
from app.tasks.importtasks import check_update_config
from app.utils import *
from . import bp
from . import bp, get_package_tabs
@bp.route("/packages/<author>/<name>/releases/", methods=["GET", "POST"])
@is_package_page
def list_releases(package):
return render_template("packages/releases_list.html",
package=package,
tabs=get_package_tabs(current_user, package), current_tab="releases")
def get_mt_releases(is_max):
@ -61,6 +69,7 @@ class EditPackageReleaseForm(FlaskForm):
query_factory=lambda: get_mt_releases(True), get_pk=lambda a: a.id, get_label=lambda a: a.name)
submit = SubmitField("Save")
@bp.route("/packages/<author>/<name>/releases/new/", methods=["GET", "POST"])
@login_required
@is_package_page
@ -162,7 +171,7 @@ def edit_release(package, id):
release.approved = False
db.session.commit()
return redirect(package.getDetailsURL())
return redirect(package.getReleaseListURL())
return render_template("packages/release_edit.html", package=package, release=release, form=form)
@ -202,7 +211,7 @@ def bulk_change_release(package):
db.session.commit()
return redirect(package.getDetailsURL())
return redirect(package.getReleaseListURL())
return render_template("packages/release_bulk_change.html", package=package, form=form)
@ -216,7 +225,7 @@ def delete_release(package, id):
abort(404)
if not release.checkPerm(current_user, Permission.DELETE_RELEASE):
return redirect(release.getEditURL())
return redirect(release.getReleaseListURL())
db.session.delete(release)
db.session.commit()
@ -296,7 +305,7 @@ def update_config(package):
flash("Now, please create an initial release", "success")
return redirect(package.getCreateReleaseURL())
return redirect(package.getDetailsURL())
return redirect(package.getReleaseListURL())
return render_template("packages/update_config.html", package=package, form=form)

@ -23,7 +23,7 @@ from wtforms.ext.sqlalchemy.fields import QuerySelectField
from wtforms.validators import *
from app.utils import *
from . import bp
from . import bp, get_package_tabs
from app.logic.LogicError import LogicError
from app.logic.screenshots import do_create_screenshot, do_order_screenshots
@ -71,7 +71,8 @@ def screenshots(package):
form.populate_obj(package)
db.session.commit()
return render_template("packages/screenshots.html", package=package, form=form)
return render_template("packages/screenshots.html", package=package, form=form,
tabs=get_package_tabs(current_user, package), current_tab="screenshots")
@bp.route("/packages/<author>/<name>/screenshots/new/", methods=["GET", "POST"])

@ -482,6 +482,10 @@ class Package(db.Model):
return url_for("packages.create_edit",
author=self.author.username, name=self.name)
def getReleaseListURL(self):
return url_for("packages.list_releases",
author=self.author.username, name=self.name)
def getSetStateURL(self, state):
if type(state) == str:
state = PackageState[state]

@ -0,0 +1,51 @@
{% macro render_releases(releases, package, current_user) -%}
{% for rel in releases %}
{% if rel.approved or package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE") %}
<li class="list-group-item">
{% if package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE") %}
<a class="btn btn-sm btn-primary float-right" href="{{ rel.getEditURL() }}">Edit
{% if not rel.task_id and not rel.approved and rel.checkPerm(current_user, "APPROVE_RELEASE") %}
/ Approve
{% endif %}
</a>
{% endif %}
{% if not rel.approved %}<i>{% endif %}
<a href="{{ rel.getDownloadURL() }}" rel="nofollow" download="{{ rel.getDownloadFileName() }}">
{{ rel.title }}
</a>
<span style="color:#ddd;">
{% if rel.min_rel and rel.max_rel %}
[MT {{ rel.min_rel.name }}-{{ rel.max_rel.name }}]
{% elif rel.min_rel %}
[MT {{ rel.min_rel.name }}+]
{% elif rel.max_rel %}
[MT &le;{{ rel.max_rel.name }}]
{% endif %}
</span>
<br>
<small style="color:#999;">
{% if rel.commit_hash %}
[{{ rel.commit_hash | truncate(5, end='') }}]
{% endif %}
created {{ rel.releaseDate | date }}.
</small>
{% if (package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE")) and rel.task_id %}
<a href="{{ url_for('tasks.check', id=rel.task_id, r=package.getDetailsURL()) }}">Importing...</a>
{% elif not rel.approved %}
Waiting for approval.
{% endif %}
{% if not rel.approved %}</i>{% endif %}
</li>
{% endif %}
{% else %}
<li class="list-group-item">No releases available.</li>
{% endfor %}
{% endmacro %}

@ -1,9 +1,13 @@
{% extends "base.html" %}
{% extends "packages/package_base.html" %}
{% block title %}
{{ package.title or "Create Package" }}
{% if not package and author != current_user %}
for {{ author.display_name }}
{% if package %}
{{ _("Edit - %(title)s", title=package.title) }}
{% if not package and author != current_user %}
for {{ author.display_name }}
{% endif %}
{% else %}
{{ _("Create Package") }}
{% endif %}
{% endblock %}
@ -21,15 +25,13 @@
{% endblock %}
{% block content %}
<h1>{{ _("Create Package") }}</h1>
{% if not package %}
<div class="alert alert-info">
<a class="float-right btn btn-sm btn-default" href="{{ url_for('flatpage', path='policy_and_guidance') }}">{{ _("View") }}</a>
<div class="alert alert-info">
<a class="float-right btn btn-sm btn-default" href="{{ url_for('flatpage', path='policy_and_guidance') }}">{{ _("View") }}</a>
{{ _("Have you read the Package Inclusion Policy and Guidance yet?") }}
</div>
{% if package %}
{{ _("Have you read the Package Inclusion Policy and Guidance yet?") }}
</div>
{% else %}
<div class="alert alert-secondary">
<a class="float-right btn btn-sm btn-default" href="/help/package_config/#cdbjson">{{ _("Read more") }}</a>

@ -1,14 +1,12 @@
{% extends "base.html" %}
{% extends "packages/package_base.html" %}
{% block title %}
{{ _("Edit Maintainers") }}
{% endblock %}
{% from "macros/forms.html" import render_submit_field, render_field %}
{% block content %}
<h1>{{ _("Edit Maintainers") }}</h1>
{% from "macros/forms.html" import render_submit_field, render_field %}
<p>
{{ _("Maintainers are given write access to the package.") }}
{{ _("Depending on their rank, they will be able to edit the package, create releases and screenshots, and read private threads.") }}

@ -0,0 +1,40 @@
{% extends "base.html" %}
{% block container %}
{% if tabs %}
<nav class="pt-4 tabs-container">
<div class="container">
<a class="float-right btn btn-primary" href="{{ package.getDetailsURL() }}">
{{ _("View Package") }}
</a>
<h1 class="mb-5">
<a href="{{ package.getDetailsURL() }}">
{{ package.title }}
</a>
</h1>
<ul class="nav nav-tabs">
{% for item in tabs %}
<li class="nav-item">
<a href="{{ item.url }}" class="nav-link {% if item.id == current_tab %}active{% endif %}">
{{ item.title }}
</a>
</li>
{% endfor %}
</ul>
</div>
</nav>
{% endif %}
{% if tabs %}
<main class="container mt-5">
{{ self.content() }}
</main>
{% else %}
<main class="container mt-4">
<h1 class="mb-4">{{ self.title() }}</h1>
{{ self.content() }}
</main>
{% endif %}
{% endblock %}

@ -1,11 +1,10 @@
{% extends "base.html" %}
{% extends "packages/package_base.html" %}
{% block title %}
Edit release | {{ package.title }}
Edit release - {{ package.title }}
{% endblock %}
{% block content %}
<h2>{{ _("Edit Release") }}</h2>
{% from "macros/forms.html" import render_field, render_submit_field, render_checkbox_field %}
<form method="POST" action="">
{{ form.hidden_tag() }}

@ -0,0 +1,38 @@
{% extends "packages/package_base.html" %}
{% block title %}
{{ _("Releases - %(title)s", title=package.title) }}
{% endblock %}
{% block content %}
<p class="float-right">
{% if package.update_config %}
<a class="btn btn-secondary" href="{{ package.getUpdateConfigURL() }}">
<i class="fas fa-cog mr-1"></i>
{{ _("Update settings") }}
</a>
{% elif package.repo %}
<a class="btn btn-secondary" href="{{ package.getSetupReleasesURL() }}">
<i class="fas fa-hat-wizard mr-1"></i>
{{ _("Set up automatic releases") }}
</a>
{% endif %}
<a class="btn btn-secondary ml-1" href="{{ package.getBulkReleaseURL() }}">
<i class="fas fa-wrench mr-1"></i>
Bulk update
</a>
<a class="btn btn-primary ml-1" href="{{ package.getCreateReleaseURL() }}">
<i class="fas fa-plus mr-1"></i>
Create
</a>
</p>
<h2 class="mt-0">{{ _("Releases") }}</h2>
<ul class="list-group">
{% from "macros/releases.html" import render_releases %}
{{ render_releases(package.releases, package, current_user) }}
</ul>
{% endblock %}

@ -1,14 +1,12 @@
{% extends "base.html" %}
{% extends "packages/package_base.html" %}
{% block title %}
Delete | {{ package.title }}
Remove {{ package.title }}
{% endblock %}
{% block content %}
<form class="card mb-3" style="max-width: 40rem; margin: auto;" method="POST" action="" >
<h3 class="card-header">Remove {{ package.title }}</h3>
<div class="card-body">
<form method="POST" action="">
<h2>Remove {{ package.title }}</h2>
<p>
In order to avoid data loss, you cannot permanently delete packages.
You can remove them from ContentDB, which will cause them to not be
@ -32,6 +30,5 @@ Delete | {{ package.title }}
{% if package.approved %}
<input type="submit" name="unapprove" value="Unapprove" class="btn btn-warning" />
{% endif %}
</div>
</form>
</form>
{% endblock %}

@ -1,14 +1,13 @@
{% extends "base.html" %}
{% extends "packages/package_base.html" %}
{% block title %}
Screenshots | {{ package.title }}
Screenshots - {{ package.title }}
{% endblock %}
{% block content %}
<h1 class="mb-5"><a href="{{ package.getDetailsURL() }}">{{ package.title }}</a></h1>
{% if package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
<a href="{{ package.getNewScreenshotURL() }}" class="btn btn-primary float-right">
<i class="fas fa-plus mr-1"></i>
{{ _("Add Image") }}
</a>
{% endif %}

@ -446,70 +446,14 @@
<h3>
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
<div class="btn-group float-right">
<a class="btn btn-secondary btn-sm ml-1" href="{{ package.getBulkReleaseURL() }}">
<i class="fas fa-wrench"></i>
{{ _("Bulk") }}
</a>
<a class="btn btn-primary btn-sm" href="{{ package.getCreateReleaseURL() }}"><i class="fas fa-plus"></i></a>
</div>
<a class="btn btn-primary btn-sm float-right" href="{{ package.getCreateReleaseURL() }}"><i class="fas fa-plus"></i></a>
{% endif %}
{{ _("Releases") }}
<a href="{{ package.getReleaseListURL() }}">{{ _("Releases") }}</a>
</h3>
<ul class="list-group">
{% for rel in releases %}
{% if rel.approved or package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE") %}
<li class="list-group-item">
{% if package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE") %}
<a class="btn btn-sm btn-primary float-right" href="{{ rel.getEditURL() }}">Edit
{% if not rel.task_id and not rel.approved and rel.checkPerm(current_user, "APPROVE_RELEASE") %}
/ Approve
{% endif %}
</a>
{% endif %}
{% if not rel.approved %}<i>{% endif %}
<a href="{{ rel.getDownloadURL() }}" rel="nofollow"
download="{{ rel.getDownloadFileName() }}">
{{ rel.title }}
</a>
<span style="color:#ddd;">
{% if rel.min_rel and rel.max_rel %}
[MT {{ rel.min_rel.name }}-{{ rel.max_rel.name }}]
{% elif rel.min_rel %}
[MT {{ rel.min_rel.name }}+]
{% elif rel.max_rel %}
[MT &le;{{ rel.max_rel.name }}]
{% endif %}
</span>
<br>
<small style="color:#999;">
{% if rel.commit_hash %}
[{{ rel.commit_hash | truncate(5, end='') }}]
{% endif %}
created {{ rel.releaseDate | date }}.
</small>
{% if (package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE")) and rel.task_id %}
<a href="{{ url_for('tasks.check', id=rel.task_id, r=package.getDetailsURL()) }}">Importing...</a>
{% elif not rel.approved %}
Waiting for approval.
{% endif %}
{% if not rel.approved %}</i>{% endif %}
</li>
{% endif %}
{% else %}
<li class="list-group-item">No releases available.</li>
{% endfor %}
{% from "macros/releases.html" import render_releases %}
{{ render_releases(releases, package, current_user) }}
</ul>
<h3>
{% if package.approved and package.checkPerm(current_user, "CREATE_THREAD") %}
<div class="btn-group float-right">