mirror of
https://github.com/pretix/pretix.git
synced 2026-05-07 15:34:02 +00:00
Organizer-level plugins (#5305)
* Add version notes to the docs * Adapt signal handling * Add UI * Add API * API and tests * Fix registry * Update doc/development/api/plugins.rst Co-authored-by: Felix Rindt <felix@rindt.me> * Fix failing tests * Apply suggestions from code review Co-authored-by: Richard Schreiber <schreiber@rami.io> * Update src/pretix/control/templates/pretixcontrol/organizers/plugin_events.html Co-authored-by: luelista <weller@rami.io> * Update src/pretix/control/templates/pretixcontrol/organizers/plugins.html Co-authored-by: luelista <weller@rami.io> * Update src/pretix/control/templates/pretixcontrol/organizers/plugins.html Co-authored-by: luelista <weller@rami.io> * Update src/pretix/control/navigation.py Co-authored-by: luelista <weller@rami.io> * Update src/pretix/control/urls.py Co-authored-by: luelista <weller@rami.io> * Apply suggestion from @wiffbi * REbase migration * Fix review note * Fix test cases * Remove plugin from all events if disabled on org level * Update doc/development/api/plugins.rst * Unify registries * Rebase migration --------- Co-authored-by: Felix Rindt <felix@rindt.me> Co-authored-by: Richard Schreiber <schreiber@rami.io> Co-authored-by: luelista <weller@rami.io>
This commit is contained in:
@@ -87,6 +87,17 @@
|
||||
<span class="text-muted">{% trans "Not available" %}</span>
|
||||
</div>
|
||||
{% elif is_active %}
|
||||
{% if plugin.level == "organizer" %}
|
||||
<p class="text-muted">
|
||||
<span class="fa fa-group" aria-hidden="true"></span>
|
||||
{% trans "This plugin can only be disabled for the entire organizer account." %}
|
||||
</p>
|
||||
{% elif plugin.level == "event_organizer" %}
|
||||
<p class="text-muted">
|
||||
<span class="fa fa-group" aria-hidden="true"></span>
|
||||
{% trans "After disabling this plugin, some functionality may remain active in the organizer account." %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="plugin-action flip">
|
||||
{% if navigation_links %}
|
||||
<div class="btn-group">
|
||||
@@ -112,14 +123,42 @@
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button class="btn btn-default{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
|
||||
value="disable">{% trans "Disable" %}</button>
|
||||
{% if plugin.level == "organizer" %}
|
||||
<a href="{% url "control:organizer.settings.plugins" organizer=request.organizer.slug %}?q={{ plugin.module|urlencode }}"
|
||||
class="btn btn-default" target="_blank">
|
||||
<span class="fa fa-external-link" aria-hidden="true"></span>
|
||||
{% trans "Open in organizer settings" %}
|
||||
</a>
|
||||
{% else %}
|
||||
<button class="btn btn-default{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
|
||||
value="disable">{% trans "Disable" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="plugin-action flip">
|
||||
<button class="btn btn-primary{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
|
||||
value="enable">{% trans "Enable" %}</button>
|
||||
</div>
|
||||
{% if plugin.level == "organizer" %}
|
||||
<p class="text-muted">
|
||||
<span class="fa fa-group" aria-hidden="true"></span>
|
||||
{% trans "This plugin can only be enabled for the entire organizer account." %}
|
||||
</p>
|
||||
<div class="plugin-action flip">
|
||||
<a href="{% url "control:organizer.settings.plugins" organizer=request.organizer.slug %}?q={{ plugin.module|urlencode }}"
|
||||
class="btn btn-default" target="_blank">
|
||||
<span class="fa fa-external-link" aria-hidden="true"></span>
|
||||
{% trans "Open in organizer settings" %}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if plugin.level == "event_organizer" and not plugin.module in request.organizer.get_plugins %}
|
||||
<p class="text-muted">
|
||||
<span class="fa fa-group" aria-hidden="true"></span>
|
||||
{% trans "Enabling this plugin will enable some of its functionality for the entire organizer account." %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="plugin-action flip">
|
||||
<button class="btn btn-primary{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
|
||||
value="enable">{% trans "Enable" %}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if plugin.featured %}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
{% extends "pretixcontrol/organizers/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% load money %}
|
||||
{% block title %}
|
||||
{% blocktrans trimmed with name=plugin.name %}
|
||||
Events with plugin {{ name }}
|
||||
{% endblocktrans %}
|
||||
{% endblock %}
|
||||
{% block inner %}
|
||||
<h1>
|
||||
{% blocktrans trimmed with name=plugin.name %}
|
||||
Events with plugin {{ name }}
|
||||
{% endblocktrans %}
|
||||
</h1>
|
||||
{% if plugin.level == "event" %}
|
||||
<p>
|
||||
{% blocktrans trimmed with name=plugin.name %}
|
||||
The plugin "{{ name }}" can be enabled or disabled for every event individually.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% elif plugin.level == "event_organizer" %}
|
||||
<p>
|
||||
{% blocktrans trimmed with name=plugin.name %}
|
||||
The plugin "{{ name }}" is enabled for your organizer account, but also needs to be enabled for the
|
||||
specific events you want to use it with.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Using this form, you can quickly enable or disable it for many events. Note that it might still
|
||||
be necessary to configure the plugin for each event individually.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<form class="form-horizontal" action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form layout="control" %}
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,193 @@
|
||||
{% extends "pretixcontrol/organizers/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load bootstrap3 %}
|
||||
{% block content %}
|
||||
<h1>{% trans "Available plugins" %}</h1>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
On this page, you can choose plugins you want to enable for your organizer account. Plugins might bring additional
|
||||
software functionality, connect your events to third-party services, or apply other forms of customizations.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% if "success" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "Your changes have been saved." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<p><input type="search" id="plugin_search_input" class="form-control" placeholder="{% trans "Search" %}"></p>
|
||||
</div>
|
||||
<div class="col-lg-2 text-right">
|
||||
<p class="btn-group btn-group-flex" data-toggle="buttons">
|
||||
<label class="btn btn-primary-if-active active"><input type="radio" name="plugin_state_filter" value="all" checked> {% trans "All" %}</label>
|
||||
<label class="btn btn-primary-if-active"><input type="radio" name="plugin_state_filter" value="active"> {% trans "Active" %}</label>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<form action="" method="post" class="form-horizontal form-plugins">
|
||||
{% csrf_token %}
|
||||
<div id="plugin_search_results" class="panel panel-default collapse">
|
||||
<div class="panel-heading">
|
||||
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{% trans "Search results" %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="plugin-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="plugin_tabs"><div class="tabbed-form">
|
||||
{% for cat, catlabel, plist, has_pictures in plugins %}
|
||||
<fieldset data-plugin-category="{{ cat }}" data-plugin-category-label="{{ catlabel }}">
|
||||
<legend>{{ catlabel }}</legend>
|
||||
<div class="plugin-list">
|
||||
{% for plugin, is_active, settings_links, navigation_links, events_counter in plist %}
|
||||
<div class="plugin-container {% if plugin.featured %}featured-plugin{% endif %}" id="plugin_{{ plugin.module }}" data-plugin-module="{{ plugin.module }}" data-plugin-name="{{ plugin.name }}">
|
||||
{% if plugin.featured %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
{% endif %}
|
||||
<div class="plugin-text">
|
||||
{% if plugin.featured or plugin.experimental %}
|
||||
<p class="text-muted">
|
||||
{% if plugin.featured %}
|
||||
<span class="fa fa-thumbs-up" aria-hidden="true"></span>
|
||||
{% trans "Top recommendation" %}
|
||||
{% endif %}
|
||||
{% if plugin.experimental %}
|
||||
<span class="fa fa-flask" aria-hidden="true"></span>
|
||||
{% trans "Experimental feature" %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if plugin.picture %}
|
||||
<p><img src="{% static plugin.picture %}" class="plugin-picture"></p>
|
||||
{% endif %}
|
||||
<h4>
|
||||
{{ plugin.name }}
|
||||
{% if show_meta %}
|
||||
<span class="text-muted text-sm">{{ plugin.version }}</span>
|
||||
{% endif %}
|
||||
{% if is_active and level == "organizer" %}
|
||||
<span class="label label-success" data-is-active>
|
||||
<span class="fa fa-check" aria-hidden="true"></span>
|
||||
{% trans "Active" %}
|
||||
</span>
|
||||
{% elif events_counter == events_total %}
|
||||
<span class="label label-success" data-is-active>
|
||||
<span class="fa fa-check" aria-hidden="true"></span>
|
||||
{% trans "Active (all events)" %}
|
||||
</span>
|
||||
{% elif events_counter %}
|
||||
<span class="label label-info" data-is-active>
|
||||
<span class="fa fa-check" aria-hidden="true"></span>
|
||||
{% blocktrans trimmed count count=events_counter %}
|
||||
Active ({{ count }} event)
|
||||
{% plural %}
|
||||
Active ({{ count }} events)
|
||||
{% endblocktrans %}
|
||||
</span>
|
||||
{% elif level == "event_organizer" %}
|
||||
<span class="label label-info" data-is-active>
|
||||
<span class="fa fa-check" aria-hidden="true"></span>
|
||||
{% blocktrans trimmed count count=0 %}
|
||||
Active ({{ count }} event)
|
||||
{% plural %}
|
||||
Active ({{ count }} events)
|
||||
{% endblocktrans %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</h4>
|
||||
{% include "pretixcontrol/event/fragment_plugin_description.html" with plugin=plugin %}
|
||||
</div>
|
||||
{% if plugin.app.compatibility_errors %}
|
||||
<div class="plugin-action">
|
||||
<span class="text-muted">{% trans "Incompatible" %}</span>
|
||||
</div>
|
||||
{% elif plugin.restricted and plugin.module not in request.organizer.settings.allowed_restricted_plugins %}
|
||||
<div class="plugin-action">
|
||||
<span class="text-muted">{% trans "Not available" %}</span>
|
||||
</div>
|
||||
{% elif is_active %}
|
||||
{% if plugin.level == "event_organizer" %}
|
||||
<p class="text-muted">
|
||||
<span class="fa fa-calendar" aria-hidden="true"></span>
|
||||
{% trans "Parts of this plugin can be enabled or disabled for events individually." %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="plugin-action flip">
|
||||
{% if navigation_links %}
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default dropdown-toggle{% if plugin.featured %} btn-lg{% endif %}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="{% trans "Open plugin settings" %}">
|
||||
<span class="fa fa-compass"></span> {% trans "Go to" %} <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% for link in navigation_links %}
|
||||
<li><a href="{{ link.0 }}">{{ link.1 }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if settings_links %}
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default dropdown-toggle{% if plugin.featured %} btn-lg{% endif %}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="{% trans "Open plugin settings" %}">
|
||||
<span class="fa fa-cog"></span> {% trans "Settings" %} <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% for link in settings_links %}
|
||||
<li><a href="{{ link.0 }}">{{ link.1 }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button class="btn btn-default{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
|
||||
value="disable">{% trans "Disable" %}</button>
|
||||
{% if plugin.level == "event_organizer" %}
|
||||
<a class="btn btn-default {% if plugin.featured %} btn-lg{% endif %}"
|
||||
href="{% url "control:organizer.settings.plugin-events" organizer=request.organizer.slug plugin=plugin.module %}">
|
||||
{% trans "Manage events" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{% if plugin.level == "organizer" %}
|
||||
<div class="plugin-action flip">
|
||||
<button class="btn btn-primary{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
|
||||
value="enable">{% trans "Enable" %}</button>
|
||||
</div>
|
||||
{% elif not plugin.level or plugin.level == "event" %}
|
||||
<p class="text-muted">
|
||||
<span class="fa fa-calendar" aria-hidden="true"></span>
|
||||
{% trans "This plugin can be enabled or disabled for events individually." %}
|
||||
</p>
|
||||
<div class="plugin-action flip">
|
||||
<a class="btn btn-default {% if plugin.featured %} btn-lg{% endif %}"
|
||||
href="{% url "control:organizer.settings.plugin-events" organizer=request.organizer.slug plugin=plugin.module %}">
|
||||
{% trans "Manage events" %}
|
||||
</a>
|
||||
</div>
|
||||
{% elif plugin.level == "event_organizer" %}
|
||||
<p class="text-muted">
|
||||
<span class="fa fa-calendar" aria-hidden="true"></span>
|
||||
{% trans "Parts of this plugin can be enabled or disabled for events individually." %}
|
||||
</p>
|
||||
<div class="plugin-action flip">
|
||||
<button class="btn btn-primary{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
|
||||
value="enable">{% trans "Enable" %}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if plugin.featured %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</fieldset>
|
||||
{% endfor %}
|
||||
</div></div>
|
||||
</form>
|
||||
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/plugins.js" %}"></script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user