mirror of
https://github.com/pretix/pretix.git
synced 2026-05-08 15:44:02 +00:00
Pluggable permissions (#5728)
* Data model draft * Refactor query and assignment usages of old permissions * Backend UI * API serializer * Big string replace * Docs, tests and fixes for teams api * Update docs for device auth * Eliminate old names * Make tests pass * Use new permissions, remove inconsistencies * Add test for translations * Show plugin permissions * Add permission for seating plans * Fix plugin activation * Fix failing test * Refactor to permission groups * Update doc/api/resources/devices.rst Co-authored-by: luelista <weller@rami.io> * Update doc/api/resources/events.rst Co-authored-by: luelista <weller@rami.io> * Update src/pretix/api/serializers/organizer.py Co-authored-by: luelista <weller@rami.io> * Fix typo * Fix python version compat * Replacement after rebase * Add proper permission handling for exports * Docs for exporters * Runtime linting of permission names * Fix typos * Show export page even without orders permission * More legacy compat * Do not strongly validate before plugins are loaded * Rebase migration * Add permission for outgoing mails * Review notes * Update doc/api/resources/teams.rst Co-authored-by: Richard Schreiber <schreiber@pretix.eu> * Clean up logic around exporters * Review and failures * Fix migration leading to forbidden combination * Handle permissions on event copying * Remove print-statements * Make test clearer * Review feedback * Add AnyPermissionOf * migration safety --------- Co-authored-by: luelista <weller@rami.io> Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
This commit is contained in:
@@ -33,6 +33,13 @@ $(function () {
|
||||
dependents[cleanName($(this).attr("name"))] = $(this)
|
||||
})
|
||||
|
||||
const dependentsDisabled = [];
|
||||
for (var k in dependents) {
|
||||
if (dependents[k].prop("disabled")) {
|
||||
dependentsDisabled.push(k);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Object.values(dependents).some((el) => el.length)) {
|
||||
// No address fields found, do not create request
|
||||
return;
|
||||
@@ -101,7 +108,7 @@ $(function () {
|
||||
label.append('<i class="label-required">' + gettext('required') + '</i>')
|
||||
}
|
||||
}
|
||||
for (var k in dependents) dependents[k].prop("disabled", false);
|
||||
for (var k in dependents) dependents[k].prop("disabled", dependentsDisabled.includes(k));
|
||||
loader.hide();
|
||||
}
|
||||
|
||||
@@ -158,7 +165,7 @@ $(function () {
|
||||
required = false;
|
||||
|
||||
dependent.closest(".form-group").toggle(visible).toggleClass('required', required);
|
||||
dependent.prop("required", required).prop("disabled", false);
|
||||
dependent.prop("required", required).prop("disabled", dependentsDisabled.includes(k));
|
||||
}
|
||||
}).finally(function () {
|
||||
loader.hide();
|
||||
|
||||
@@ -340,11 +340,12 @@ var form_handlers = function (el) {
|
||||
}
|
||||
|
||||
el.find("input[data-checkbox-dependency]").each(function () {
|
||||
var initially_disabled = $(this).prop("disabled");
|
||||
var dependent = $(this),
|
||||
dependency = findDependency($(this).attr("data-checkbox-dependency"), this),
|
||||
update = function () {
|
||||
var enabled = dependency.prop('checked');
|
||||
dependent.prop('disabled', !enabled).closest('.form-group, .form-field-boundary').toggleClass('disabled', !enabled);
|
||||
dependent.prop('disabled', !enabled || initially_disabled).closest('.form-group, .form-field-boundary').toggleClass('disabled', !enabled);
|
||||
if (!enabled && !dependent.is('[data-checkbox-dependency-visual]')) {
|
||||
dependent.prop('checked', false);
|
||||
dependent.trigger('change')
|
||||
@@ -366,11 +367,12 @@ var form_handlers = function (el) {
|
||||
});
|
||||
|
||||
el.find("div[data-display-dependency], textarea[data-display-dependency], input[data-display-dependency], select[data-display-dependency], button[data-display-dependency]").each(function () {
|
||||
var initially_disabled = $(this).prop("disabled");
|
||||
var dependent = $(this),
|
||||
dependency = findDependency($(this).attr("data-display-dependency"), this),
|
||||
update = function (ev) {
|
||||
var enabled = dependency.toArray().some(function(d) {
|
||||
if (d.disabled) return false;
|
||||
if (d.disabled && !initially_disabled) return false;
|
||||
if (d.type === 'checkbox' || d.type === 'radio') {
|
||||
return d.checked;
|
||||
} else if (d.type === 'select-one') {
|
||||
@@ -391,7 +393,7 @@ var form_handlers = function (el) {
|
||||
}
|
||||
var $toggling = dependent;
|
||||
if (dependent.is("[data-disable-dependent]")) {
|
||||
$toggling.attr('disabled', !enabled).trigger("change");
|
||||
$toggling.attr('disabled', !enabled || initially_disabled).trigger("change");
|
||||
}
|
||||
const tagName = dependent.get(0).tagName.toLowerCase()
|
||||
if (tagName !== "div" && tagName !== "button") {
|
||||
|
||||
@@ -417,6 +417,30 @@ div.scrolling-multiple-choice, div.scrolling-choice {
|
||||
}
|
||||
}
|
||||
}
|
||||
.team-permission-groups {
|
||||
border: 1px solid $input-border;
|
||||
border-radius: $input-border-radius;
|
||||
padding: 10px 15px;
|
||||
|
||||
.radio {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
&:not(:has(.fa-fw)) {
|
||||
// Visual adjustment between options with and without help text
|
||||
&:after {
|
||||
display: inline-block;
|
||||
content: " ";
|
||||
padding-right: 1.28571em;
|
||||
}
|
||||
}
|
||||
}
|
||||
.control-label {
|
||||
text-align: left;
|
||||
}
|
||||
.form-group:last-child, .help-block {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
table td > .checkbox {
|
||||
margin: 0;
|
||||
position: static;
|
||||
|
||||
Reference in New Issue
Block a user