Compare commits

...

2 Commits

Author SHA1 Message Date
rubenwardy a93eea8612 Use vertical nav 2021-05-07 23:12:49 +01:00
rubenwardy a6ab2d6f79 Unify package edit UI 2021-05-07 23:12:47 +01:00
14 changed files with 228 additions and 104 deletions

View File

@ -16,6 +16,42 @@
from flask import Blueprint from flask import Blueprint
from app.models import User, Package, Permission
bp = Blueprint("packages", __name__) 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 from . import packages, screenshots, releases, reviews

View File

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

View File

@ -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.rediscache import has_key, set_key, make_download_key
from app.tasks.importtasks import check_update_config from app.tasks.importtasks import check_update_config
from app.utils import * 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): 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) query_factory=lambda: get_mt_releases(True), get_pk=lambda a: a.id, get_label=lambda a: a.name)
submit = SubmitField("Save") submit = SubmitField("Save")
@bp.route("/packages/<author>/<name>/releases/new/", methods=["GET", "POST"]) @bp.route("/packages/<author>/<name>/releases/new/", methods=["GET", "POST"])
@login_required @login_required
@is_package_page @is_package_page
@ -162,7 +171,7 @@ def edit_release(package, id):
release.approved = False release.approved = False
db.session.commit() db.session.commit()
return redirect(package.getDetailsURL()) return redirect(package.getReleaseListURL())
return render_template("packages/release_edit.html", package=package, release=release, form=form) 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() db.session.commit()
return redirect(package.getDetailsURL()) return redirect(package.getReleaseListURL())
return render_template("packages/release_bulk_change.html", package=package, form=form) return render_template("packages/release_bulk_change.html", package=package, form=form)
@ -216,7 +225,7 @@ def delete_release(package, id):
abort(404) abort(404)
if not release.checkPerm(current_user, Permission.DELETE_RELEASE): if not release.checkPerm(current_user, Permission.DELETE_RELEASE):
return redirect(release.getEditURL()) return redirect(release.getReleaseListURL())
db.session.delete(release) db.session.delete(release)
db.session.commit() db.session.commit()
@ -296,7 +305,7 @@ def update_config(package):
flash("Now, please create an initial release", "success") flash("Now, please create an initial release", "success")
return redirect(package.getCreateReleaseURL()) return redirect(package.getCreateReleaseURL())
return redirect(package.getDetailsURL()) return redirect(package.getReleaseListURL())
return render_template("packages/update_config.html", package=package, form=form) return render_template("packages/update_config.html", package=package, form=form)

View File

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

View File

@ -473,6 +473,10 @@ class Package(db.Model):
return url_for("packages.create_edit", return url_for("packages.create_edit",
author=self.author.username, name=self.name) 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): def getSetStateURL(self, state):
if type(state) == str: if type(state) == str:
state = PackageState[state] state = PackageState[state]

View File

@ -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 %}

View File

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

View File

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

View File

@ -0,0 +1,33 @@
{% extends "base.html" %}
{% block container %}
<main class="container mt-4">
<div class="row">
{% if tabs %}
<div class="col-md-3 mb-4">
<div class="list-group">
<a class="list-group-item list-group-item-action" href="{{ package.getDetailsURL() }}">
<span class="row m-0 p-0">
<span class="col-auto m-0 p-0">
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ package.getThumbnailURL() }}" alt="Thumbnail" style="max-height: 20px;">
</span>
<span class="col m-0 p-0 pl-2">
{{ package.title }}
</span>
</span>
</a>
{% for item in tabs %}
<a href="{{ item.url }}"
class="list-group-item list-group-item-action {% if item.id == current_tab %}active{% endif %}">
{{ item.title }}
</a>
{% endfor %}
</div>
</div>
{% endif %}
<div class="col {% if not tabs %}mt-4{% endif %}">
{{ self.content() }}
</div>
</div>
</main>
{% endblock %}

View File

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

View File

@ -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 %}

View File

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

View File

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

View File

@ -441,70 +441,14 @@
<h3> <h3>
{% if package.checkPerm(current_user, "MAKE_RELEASE") %} {% if package.checkPerm(current_user, "MAKE_RELEASE") %}
<div class="btn-group float-right"> <a class="btn btn-primary btn-sm float-right" href="{{ package.getCreateReleaseURL() }}"><i class="fas fa-plus"></i></a>
<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>
{% endif %} {% endif %}
{{ _("Releases") }} <a href="{{ package.getReleaseListURL() }}">{{ _("Releases") }}</a>
</h3> </h3>
<ul class="list-group"> <ul class="list-group">
{% for rel in releases %} {% from "macros/releases.html" import render_releases %}
{% if rel.approved or package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE") %} {{ render_releases(releases, package, current_user) }}
<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 %}
</ul> </ul>
<h3> <h3>
{% if package.approved and package.checkPerm(current_user, "CREATE_THREAD") %} {% if package.approved and package.checkPerm(current_user, "CREATE_THREAD") %}
<div class="btn-group float-right"> <div class="btn-group float-right">