mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2026-03-05 12:01:32 +01:00
(CRUDP): Initial page permissions crudp field
This commit is contained in:
@@ -5,14 +5,30 @@ const body = $('body');
|
||||
body.on('change', '[data-acl_picker] select', (event) => {
|
||||
const target = $(event.currentTarget);
|
||||
const value = target.val();
|
||||
const inputs = target.closest('.permissions-item').find('input[name]');
|
||||
const item = target.closest('.permissions-item');
|
||||
const inputs = item.find('input[name]');
|
||||
const wrapper = target.closest('[data-acl_picker_id]');
|
||||
const type = item.data('fieldType');
|
||||
|
||||
inputs.each((index, input) => {
|
||||
input = $(input);
|
||||
const name = input.prop('name');
|
||||
input.prop('name', name.replace(/(.*)(\[[^\]]*\])/, `$1[${value}]`));
|
||||
});
|
||||
if (type === 'access') {
|
||||
inputs.each((index, input) => {
|
||||
input = $(input);
|
||||
const name = input.prop('name');
|
||||
input.prop('name', name.replace(/(.*)(\[[^\]]*\])/, `$1[${value}]`));
|
||||
});
|
||||
} else if (type === 'permissions') {
|
||||
const crudpContainer = item.find('[data-field-name]');
|
||||
inputs.each((index, input) => {
|
||||
input = $(input);
|
||||
const rand = Math.round(Math.random() * 500);
|
||||
const name = crudpContainer.data('fieldName');
|
||||
const id = input.prop('id').split('_').slice(0, -1).join('_') + `_${value}+${rand}`;
|
||||
const key = input.data('crudpKey');
|
||||
input.prop('name', name.replace(/(.*)(\[[^\]]*\])/, `$1[${value}][${key}]`));
|
||||
input.prop('id', id);
|
||||
input.next('label').prop('for', id);
|
||||
});
|
||||
}
|
||||
|
||||
wrapper.find('.permissions-item .button.add-item')[!value ? 'addClass' : 'removeClass']('disabled').prop('disabled', !value ? 'disabled' : null);
|
||||
});
|
||||
|
||||
50
themes/grav/app/forms/fields/indeterminate.js
Normal file
50
themes/grav/app/forms/fields/indeterminate.js
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
document.addEventListener('click', (event) => {
|
||||
if (document.querySelector('#pages-filters')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const wrapper = event.target.closest('.checkboxes.indeterminate');
|
||||
|
||||
if (wrapper) {
|
||||
event.preventDefault();
|
||||
const checkbox = wrapper.querySelector('input[type="checkbox"]:not([disabled])');
|
||||
const checkStatus = wrapper.dataset._checkStatus;
|
||||
wrapper.classList.remove('status-checked', 'status-unchecked', 'status-indeterminate');
|
||||
|
||||
switch (checkStatus) {
|
||||
// checked, going indeterminate
|
||||
case '1':
|
||||
wrapper.dataset._checkStatus = '2';
|
||||
checkbox.indeterminate = true;
|
||||
checkbox.checked = false;
|
||||
checkbox.value = 0;
|
||||
wrapper.classList.add('status-indeterminate');
|
||||
break;
|
||||
|
||||
// indeterminate, going unchecked
|
||||
case '2':
|
||||
wrapper.dataset._checkStatus = '0';
|
||||
checkbox.indeterminate = false;
|
||||
checkbox.checked = false;
|
||||
checkbox.value = ' ';
|
||||
wrapper.classList.add('status-unchecked');
|
||||
break;
|
||||
|
||||
// unchecked, going checked
|
||||
case '0':
|
||||
default:
|
||||
wrapper.dataset._checkStatus = '1';
|
||||
checkbox.indeterminate = false;
|
||||
checkbox.checked = true;
|
||||
checkbox.value = 1;
|
||||
wrapper.classList.add('status-checked');
|
||||
break;
|
||||
}
|
||||
|
||||
const input = new CustomEvent('input', { detail: { target: checkbox }});
|
||||
document.dispatchEvent(input);
|
||||
}
|
||||
});
|
||||
|
||||
(document.querySelectorAll('input[type="checkbox"][indeterminate="true"]') || []).forEach((input) => { input.indeterminate = true; });
|
||||
@@ -15,6 +15,7 @@ import TextField, { Instance as TextFieldInstance } from './text';
|
||||
import ParentsField, { Instance as ParentsFieldInstance } from './parents';
|
||||
|
||||
import './acl-picker';
|
||||
import './indeterminate';
|
||||
|
||||
export default {
|
||||
FilepickerField: {
|
||||
|
||||
30
themes/grav/js/admin.min.js
vendored
30
themes/grav/js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -9,6 +9,8 @@
|
||||
{% set super = object.authorize('admin.super', 'test') %}
|
||||
{% endif %}
|
||||
|
||||
{% set classes = { 0: 'status-unchecked', 1: 'status-checked', ' ': 'status-indeterminate' } %}
|
||||
|
||||
{% if field.data_type == 'access' %}
|
||||
{% set groupsList = [
|
||||
{ label: 'Site', value: 'site' },
|
||||
@@ -25,35 +27,26 @@
|
||||
] %}
|
||||
{% elseif field.data_type == 'permissions' %}
|
||||
{% set groupsList = [] %}
|
||||
{% set crudp = {
|
||||
c: { title: 'Create', value: '' },
|
||||
r: { title: 'Read', value: '' },
|
||||
u: { title: 'Update', value: '' },
|
||||
d: { title: 'Delete', value: '' },
|
||||
p: { title: 'Publish', value: '' }
|
||||
} %}
|
||||
{% set optionsList = [
|
||||
{ text: 'Authors', value: 'authors', perms: {
|
||||
c: { title: 'Create', value: '' },
|
||||
r: { title: 'Read', value: 1 },
|
||||
u: { title: 'Update', value: 1 },
|
||||
d: { title: 'Delete', value: 1 },
|
||||
p: { title: 'Publish', value: 1 }
|
||||
} },
|
||||
{ text: 'Manager', value: 'manager', perms: {
|
||||
c: { title: 'Create', value: 1 },
|
||||
r: { title: 'Read', value: 0 },
|
||||
u: { title: 'Update', value: '' },
|
||||
d: { title: 'Delete', value: 1 },
|
||||
p: { title: 'Publish', value: 0 }
|
||||
} },
|
||||
{ text: 'Denied', value: 'denied', perms: {
|
||||
c: { title: 'Create', value: 0 },
|
||||
r: { title: 'Read', value: 0 },
|
||||
u: { title: 'Update', value: 0 },
|
||||
d: { title: 'Delete', value: 0 },
|
||||
p: { title: 'Publish', value: 0 }
|
||||
} }
|
||||
{ text: 'Authors', value: 'authors' },
|
||||
{ text: 'Manager', value: 'manager' },
|
||||
{ text: 'Denied', value: 'denied' }
|
||||
] %}
|
||||
{% endif %}
|
||||
|
||||
<template data-id="acl_picker-{{ field.name }}">
|
||||
<div class="permissions-item">
|
||||
<div class="permissions-item" data-field-type="{{ field.data_type }}">
|
||||
<a href="#" class="remove-item"><i class="fa fa-trash"></i></a>
|
||||
<select data-grav-selectize="{{ { options: optionsList, optgroups: groupsList }|json_encode }}"></select>
|
||||
|
||||
{% if field.data_type == 'access' %}
|
||||
<div class="switch-toggle switch-grav medium switch-3">
|
||||
<input type="radio" value="1" id="{{ field.name ~ '_' }}" name="{{ (scope ~ field.name)|fieldName ~ '[]' }}" class="label1" checked>
|
||||
|
||||
@@ -64,6 +57,24 @@
|
||||
<label for="{{ field.name ~ '_' }}">{{ tu ? 'PLUGIN_ADMIN.DENIED'|tu : 'PLUGIN_ADMIN.DENIED'|t }}</label>
|
||||
|
||||
</div>
|
||||
{% elseif field.data_type == 'permissions' %}
|
||||
<div class="crudp-container" data-field-name="{{ (scope ~ field.name)|fieldName ~ '[]' }}">
|
||||
{% for key,button in crudp %}
|
||||
<div>
|
||||
<span class="checkboxes indeterminate toggleable status-unchecked hint--top"
|
||||
data-_check-status="0"
|
||||
data-hint="{{ button.title }}">
|
||||
<input type="checkbox"
|
||||
id="{{ field.name ~ '_' ~ key ~ '_' }}"
|
||||
data-crudp-key="{{ key }}"
|
||||
name="{{ (scope ~ field.name)|fieldName ~ '[][' ~ key ~ ']' }}"
|
||||
indeterminte="false" value=" ">
|
||||
<label for="{{ field.name ~ '_' ~ key ~ '_' }}">{{ key }}</label>
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<button class="button add-item"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -74,12 +85,16 @@
|
||||
<a href="#" class="button add-item"><i class="fa fa-plus"></i></a>
|
||||
</div>
|
||||
|
||||
|
||||
value:
|
||||
{{ value|json_encode}}
|
||||
{% for key, access in value %}
|
||||
<div class="permissions-item">
|
||||
<div class="permissions-item" data-field-type="{{ field.data_type }}">
|
||||
<a href="#" class="remove-item"><i class="fa fa-trash"></i></a>
|
||||
<select data-grav-selectize="{{ { options: optionsList, optgroups: groupsList }|json_encode }}">
|
||||
<option value="{{ key }}" selected>{{ key }}</option>
|
||||
</select>
|
||||
{% if field.data_type == 'access' %}
|
||||
<div class="switch-toggle switch-grav medium switch-3">
|
||||
{% set rnd = random(100) %}
|
||||
<input type="radio" value="1" id="{{ field.name ~ '_' ~ rnd }}" name="{{ (scope ~ field.name)|fieldName ~ '[' ~ key ~ ']' }}" class="label1" {{ access ? 'checked' }}>
|
||||
@@ -92,6 +107,26 @@
|
||||
<label for="{{ field.name ~ '_' ~ rnd }}">{{ tu ? 'PLUGIN_ADMIN.DENIED'|tu : 'PLUGIN_ADMIN.DENIED'|t }}</label>
|
||||
|
||||
</div>
|
||||
{% elseif field.data_type == 'permissions' %}
|
||||
<div class="crudp-container" data-field-name="{{ (scope ~ field.name)|fieldName ~ '[]' }}">
|
||||
{% for crudp_key, button in crudp %}
|
||||
<div>
|
||||
{% set crudp_value = value[key][crudp_key] %}
|
||||
<span class="checkboxes indeterminate toggleable {{ classes[crudp_value]}} hint--top"
|
||||
data-_check-status="{{ crudp_value == ' ' ? 2 : crudp_value }}"
|
||||
data-hint="{{ button.title }}">
|
||||
<input type="checkbox"
|
||||
id="{{ field.name ~ '_' ~ crudp_key ~ '_' }}"
|
||||
data-crudp-key="{{ crudp_key }}"
|
||||
name="{{ (scope ~ field.name)|fieldName ~ '[][' ~ crudp_key ~ ']' }}"
|
||||
indeterminate="false" value=" "
|
||||
indeterminate="{{ crudp_value == ' ' ? 'true' : 'false' }}" value="{{ crudp_value }}" {% if crudp_value == 1 %}checked{% endif %}>
|
||||
<label for="{{ field.name ~ '_' ~ crudp_key ~ '_' }}">{{ crudp_key }}</label>
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<button class="button add-item"><i class="fa fa-plus"></i></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user