--- /dev/null
+{#
+/**
+ * Copyright © 2003-2024 The Galette Team
+ *
+ * This file is part of Galette (https://galette.eu).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ */
+#}
+ <div class="ui basic fitted segment loader_selector">
+ <table class="listing ui celled striped table">
+ <thead>
+ <tr>
+ <th class="id_row">#</th>
+ <th>{{ _T("Name") }}</th>
+ <th>{{ _T("Permissions") }}</th>
+ <th class="date_row">{{ _T("Required") }}</th>
+{% if preferences.pref_member_form_grid != 'one' %}
+ <th class="date_row">{{ _T("Width in forms") }}</th>
+{% endif %}
+ </tr>
+ </thead>
+ <tbody id="sortable_fields_{{ fs }}" class="sortable-items" data-category="{{ fs }}">
+{% for col, field in categorized_fields[fs] %}
+ {% if (preferences.pref_show_id or field.field_id != 'id_adh') and field.field_id != 'parent_id' %}
+ {% set fid = field.field_id %}
+ <tr>
+ <td data-scope="id" class="collapsing">
+ <i class="jsonly displaynone arrows alternate icon" aria-hidden="true"></i>
+ {{ loop.index }}
+ </td>
+ <td class="fieldname" data-scope="row">
+ <input type="hidden" name="fields[]" value="{{ fid }}"/>
+ <input type="hidden" name="{{ fid }}_category" value="{{ category.id_field_category }}"/>
+ <input type="hidden" name="{{ fid }}_label" value="{{ field.label }}"/>
+ {{ field.label }}
+ </td>
+ <td class="visibility_cell" data-col-label="{{ _T("Permissions") }}">
+ <span data-prop-label="{{ _T("Permissions") }}" class="visible" title="{{ _T("Change '%field' permissions")|replace({'%field': field.label}) }}">
+ <select name="{{ fid }}_visible" id="{{ fid }}_visible" class="ui dropdown">
+ <option value="{{ constant('Galette\\Entity\\FieldsConfig::NOBODY') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::NOBODY') %} selected="selected"{% endif %}>{{ _T("Inaccessible") }}</option>
+ <option value="{{ constant('Galette\\Entity\\FieldsConfig::ADMIN') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::ADMIN') %} selected="selected"{% endif %}>{{ _T("Administrator") }}</option>
+ <option value="{{ constant('Galette\\Entity\\FieldsConfig::STAFF') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::STAFF') %} selected="selected"{% endif %}>{{ _T("Staff member") }}</option>
+ <option value="{{ constant('Galette\\Entity\\FieldsConfig::MANAGER') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::MANAGER') %} selected="selected"{% endif %}>{{ _T("Group manager") }}</option>
+ <option value="{{ constant('Galette\\Entity\\FieldsConfig::USER_READ') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::USER_READ') %} selected="selected"{% endif %}>{{ _T("Read only") }}</option>
+ <option value="{{ constant('Galette\\Entity\\FieldsConfig::USER_WRITE') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::USER_WRITE') %} selected="selected"{% endif %}>{{ _T("Read/Write") }}</option>
+ </select>
+ </span>
+ </td>
+ <td class="required_cell" data-col-label="{{ _T("Required") }}">
+ <span data-prop-label="{{ _T("Required") }}" class="required" title="{% if fid in non_required %}{{ _T("Field '%field' cannot be set as required.")|replace({'%field': field.label}) }}{% else %}{{ _T("Mark '%field' as (not) required")|replace({'%field': field.label}) }}{% endif %}">
+ <label for="{{ fid }}_required_yes">{{ _T("Yes") }}</label>
+ <input type="radio" name="{{ fid }}_required" id="{{ fid }}_required_yes" value="1"{% if field.required %} checked="checked"{% endif %}{% if fid in non_required %} disabled="disabled"{% endif %}/>
+ <label for="{{ fid }}_required_no">{{ _T("No") }}</label>
+ <input type="radio" name="{{ fid }}_required" id="{{ fid }}_required_no" value="0"{% if not field.required %} checked="checked"{% endif %}{% if fid in non_required %} disabled="disabled"{% endif %}/>
+ </span>
+ </td>
+ {% if preferences.pref_member_form_grid != 'one' %}
+ <td class="left" data-col-label="{{ _T("Width in forms") }}">
+ <span data-prop-label="{{ _T("Width in forms") }}" title="{{ _T("Change field's width with in forms") }}">
+ <select name="{{ fid }}_width_in_forms" id="{{ fid }}_width_in_forms" class="ui dropdown">
+ <option value="1"{% if field.width_in_forms == 1 or (preferences.pref_member_form_grid == 'two' and field.width_in_forms == 3) %} selected="selected"{% endif %}>{{ _T("Default") }}</option>
+ <option value="2"{% if field.width_in_forms == 2 %} selected="selected"{% endif %}>{{ _T("Full") }}</option>
+ {% if preferences.pref_member_form_grid == 'three' %}
+ <option value="3"{% if field.width_in_forms == 3 %} selected="selected"{% endif %}>{{ _T("Half") }}</option>
+ {% endif %}
+ </select>
+ </span>
+ </td>
+ {% endif %}
+ </tr>
+ {% endif %}
+{% endfor %}
+ </tbody>
+ </table>
+ </div>
{% extends 'page.html.twig' %}
{% block content %}
- <div class="jsonly displaynone ui basic fitted segment">
- <a class="ui labeled icon button collapse">
- <i class="angle double down icon" aria-hidden="true"></i>
- {{ _T("Expand all") }}
- </a>
- </div>
<form action="{{ url_for('configureCoreFields') }}" method="post" id="config_fields_form" class="ui form">
- <div id="members_tab">
-{% for category in categories %}
- {% set catname = category.category %}
- <div class="galetteform ui styled fluid accordion field">
- <div class="ui title">
- <i class="jsonly displaynone dropdown icon" aria-hidden="true"></i>
- {{ _T(catname) }}
+ <div id="sortable_categories" class="ui stackable pointing inverted menu">
+ {% for category in categories %}
+ {% set catname = _T(category.category) %}
+ {% set fs = category.id_field_category %}
+ <a href="#{{ fs }}" class="item" data-tab="{{ fs }}">
+ <input type="hidden" name="categories[]" id="category{{ loop.index }}" value="{{ category.id_field_category }}"/>
<i class="jsonly displaynone arrows alternate icon" aria-hidden="true"></i>
- </div>
- <div class="content">
- <div class="ui basic fitted segment">
- <div class="ui {% if preferences.pref_member_form_grid != 'one' %}four{% else %}three{% endif %} column stackable grid core-fields-properties">
- <div class="middle aligned row">
- <div class="column">
- <span class="ui fluid label">{{ _T("Field name") }}</span>
- </div>
- <div class="column">
- <span class="ui fluid label">{{ _T("Required") }}</span>
- </div>
- <div class="column">
- <span class="ui fluid label">{{ _T("Permissions") }}</span>
- </div>
- {% if preferences.pref_member_form_grid != 'one' %}
- <div class="column">
- <span class="ui fluid label">{{ _T("Width in forms") }}</span>
- </div>
- {% endif %}
- </div>
- </div>
- </div>
- <ul id="sortable_{{ loop.index }}" class="sortable-items">
- {% set fs = category.id_field_category %}
- {% for col, field in categorized_fields[fs] %}
- {% if (preferences.pref_show_id or field.field_id != 'id_adh') and field.field_id != 'parent_id' %}
- {% set fid = field.field_id %}
- <li class="ui segment">
- <div class="ui {% if preferences.pref_member_form_grid != 'one' %}four{% else %}three{% endif %} column stackable grid core-fields-listing">
- <div class="middle aligned row">
- <div class="column">
- <i class="jsonly displaynone arrows alternate icon" aria-hidden="true"></i>
- <span data-prop-label="{{ _T("Field name") }}" class="fieldname">
- <input type="hidden" name="fields[]" value="{{ fid }}"/>
- <input type="hidden" name="{{ fid }}_category" value="{{ category.id_field_category }}"/>
- <input type="hidden" name="{{ fid }}_label" value="{{ field.label }}"/>
- {{ field.label }}
- </span>
- </div>
- <div class="column">
- <span data-prop-label="{{ _T("Required") }}" class="yesno" title="{% if fid in non_required %}{{ _T("Field '%field' cannot be set as required.")|replace({'%field': field.label}) }}{% else %}{{ _T("Mark '%field' as (not) required")|replace({'%field': field.label}) }}{% endif %}">
- <label for="{{ fid }}_required_yes">{{ _T("Yes") }}</label>
- <input type="radio" name="{{ fid }}_required" id="{{ fid }}_required_yes" value="1"{% if field.required %} checked="checked"{% endif %}{% if fid in non_required %} disabled="disabled"{% endif %}/>
- <label for="{{ fid }}_required_no">{{ _T("No") }}</label>
- <input type="radio" name="{{ fid }}_required" id="{{ fid }}_required_no" value="0"{% if not field.required %} checked="checked"{% endif %}{% if fid in non_required %} disabled="disabled"{% endif %}/>
- </span>
- </div>
- <div class="column">
- <span data-prop-label="{{ _T("Permissions") }}" class="access" title="{{ _T("Change '%field' permissions")|replace({'%field': field.label}) }}">
- <select name="{{ fid }}_visible" id="{{ fid }}_visible" class="ui dropdown">
- <option value="{{ constant('Galette\\Entity\\FieldsConfig::NOBODY') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::NOBODY') %} selected="selected"{% endif %}>{{ _T("Inaccessible") }}</option>
- <option value="{{ constant('Galette\\Entity\\FieldsConfig::ADMIN') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::ADMIN') %} selected="selected"{% endif %}>{{ _T("Administrator") }}</option>
- <option value="{{ constant('Galette\\Entity\\FieldsConfig::STAFF') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::STAFF') %} selected="selected"{% endif %}>{{ _T("Staff member") }}</option>
- <option value="{{ constant('Galette\\Entity\\FieldsConfig::MANAGER') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::MANAGER') %} selected="selected"{% endif %}>{{ _T("Group manager") }}</option>
- <option value="{{ constant('Galette\\Entity\\FieldsConfig::USER_READ') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::USER_READ') %} selected="selected"{% endif %}>{{ _T("Read only") }}</option>
- <option value="{{ constant('Galette\\Entity\\FieldsConfig::USER_WRITE') }}"{% if field.visible == constant('Galette\\Entity\\FieldsConfig::USER_WRITE') %} selected="selected"{% endif %}>{{ _T("Read/Write") }}</option>
- </select>
- </span>
- </div>
- {% if preferences.pref_member_form_grid != 'one' %}
- <div class="column">
- <span data-prop-label="{{ _T("Width in forms") }}" class="access" title="{{ _T("Change field's width with in forms") }}">
- <select name="{{ fid }}_width_in_forms" id="{{ fid }}_width_in_forms" class="ui dropdown">
- <option value="1"{% if field.width_in_forms == 1 %} selected="selected"{% endif %}>{{ _T("Default") }}</option>
- <option value="2"{% if field.width_in_forms == 2 %} selected="selected"{% endif %}>{{ _T("Full") }}</option>
- {% if preferences.pref_member_form_grid == 'three' %}
- <option value="3"{% if field.width_in_forms == 3 %} selected="selected"{% endif %}>{{ _T("Half") }}</option>
- {% endif %}
- </select>
- </span>
- </div>
- {% endif %}
- </div>
- </div>
- </li>
- {% endif %}
+ {{ catname }}
+ </a>
{% endfor %}
- </ul>
- </div>
- <input type="hidden" name="categories[]" id="category{{ loop.index }}" value="{{ category.id_field_category }}"/>
</div>
-{% endfor %}
- </div>
- <div class="jsonly hidden ui basic fitted segment">
- <a class="ui labeled icon button collapse">
- <i class="angle double down icon" aria-hidden="true"></i>
- {{ _T("Expand all") }}
- </a>
- </div>
+ {% for category in categories %}
+ {% set fs = category.id_field_category %}
+ <div class="ui tab segment" data-tab="{{ fs }}">
+ {% include 'elements/edit_core_fields.html.twig' %}
+ </div>
+ {% endfor %}
<div class="ui basic center aligned segment">
<button type="submit" class="ui labeled icon primary button action">
<i class="save icon" aria-hidden="true"></i> {{ _T("Save") }}
{% block javascripts %}
<script type="module">
+ $(function() {
+ $('.pointing.menu .item').tab();
+ });
var _initSortable = function(){
- var _categories = document.getElementById('members_tab');
+ var _categories = document.getElementById('sortable_categories');
var _nestedSortables = [].slice.call(document.querySelectorAll('.sortable-items'));
+ var _drag_on_tabs = null;
+
+ function changeTab() {
+ $('.pointing.menu .item').tab('change tab', this.dataset.tab);
+ }
+
for (var i = 0; i < _nestedSortables.length; i++) {
new Sortable(_nestedSortables[i], {
group: 'nested',
ghostClass: 'yellow',
fallbackOnBody: true,
swapThreshold: 0.65,
+ onStart: function (evt) {
+ const targets = document.querySelectorAll('#sortable_categories .item');
+ for (let i = 0; i < targets.length; i++) {
+ targets[i].addEventListener('dragenter', changeTab, false);
+ }
+ },
+ onEnd: function (evt) {
+ const targets = document.querySelectorAll('#sortable_categories .item');
+ for (let i = 0; i < targets.length; i++) {
+ targets[i].removeEventListener('dragenter', changeTab, false);
+ }
+ },
onAdd: function (evt) {
var _item = evt.item;
- var _category = _item.parentElement.parentElement.parentElement.querySelectorAll('input[name^=categories]')[0].attributes.value.nodeValue;
+ var _category = _item.parentElement.dataset.category;
_item.classList.add('yellow');
_item.querySelectorAll('input[name$=category]')[0].setAttribute('value', _category);
},
new Sortable(_categories, {
animation: 150,
- ghostClass: 'yellow',
onUpdate: function (evt) {
var _item = evt.item;
- _item.classList.add('yellow');
- }
- });
- }
-
-
- var _bindCollapse = function() {
- $('.collapse').click(function(){
- var _this = $(this);
- var _buttons = $('.collapse');
- var _expandTxt = '<i class="angle double down icon" aria-hidden="true"></i> {{ _T("Expand all") }}';
- var _collapseTxt = '<i class="angle double up icon" aria-hidden="true"></i> {{ _T("Collapse all") }}';
- var _isExpand = false;
- var _icon = _this.children('.icon');
- if( _icon.is('.down') ) {
- _buttons.html(_collapseTxt);
- } else {
- _isExpand = true;
- _buttons.html(_expandTxt);
- }
- if (_isExpand == true) {
- $('.ui.accordion.galetteform').accordion('close', 0);
- } else {
- $('.ui.accordion.galetteform').accordion('open', 0);
+ _item.classList.add('moved');
}
});
}
var _warnings = [];
var _checkCoherence = function(index, elt){
var _elt = $(elt);
- var _disabled = _elt.find('.yesno input:disabled, .access input:disabled');
+ var _disabled = _elt.find('.required input:disabled, .visible input:disabled');
if ( _disabled.length == 0 ) {
- var _required = parseInt(_elt.find('.yesno input:checked').val());
- var _accessible = parseInt(_elt.find('.access option:selected').val());
-
+ var _required = parseInt(_elt.find('.required input:checked').val());
+ var _visible = parseInt(_elt.find('.visible option:selected').val());
- if ( _required === 1 && _accessible === 0 ) {
- _elt.addClass('red');
+ if ( _required === 1 && _visible === 0 ) {
+ _elt.addClass('red colored');
+ _elt.find('.required_cell, .visibility_cell').addClass('left red marked');
_warnings[_warnings.length] = _elt;
}
}
$('#config_fields_form').submit(function(){
_warnings = [];
- $('#members_tab .segment').removeClass('red');
- $('.fields_list li').each(_checkCoherence);
+ $('.sortable-items tr').removeClass('red colored');
+ $('.required_cell, .visibility_cell').removeClass('left red marked');
+ $('.sortable-items tr').each(_checkCoherence);
if ( _warnings.length > 0 ) {
- var _w = $('#warnings');
-
- _w.find('li').remove();
+ document.getElementById('galette_body').scrollTo({top: 0});
+ var _message = '{{ _T("Some warnings has been thrown:")|e("js") }}<ul>';
$.each(_warnings, function(i,w){
var _val = w[0].getElementsByClassName('fieldname')[0].textContent.trim();
- _w.find('ul').append('<li>' + _val + '</li>');
+ _message += '<li>' + _val + '</li>';
});
-
- {% include "elements/js/modal.js.twig" with {
- modal_title: "_w.find('.header')",
- modal_content: "_w.find('.content')",
- modal_class: "tiny",
- modal_deny_only: true,
- modal_cancel_text: _T("Close")|e("js"),
- modal_classname: "redalert",
- } %}
+ _message += '</ul>{{ _T("Please correct above warnings to continue.") }}';
+ $('body')
+ .toast({
+ title: '{{ _T("Warning")|e("js") }}',
+ displayTime: 0,
+ closeIcon: true,
+ position: 'top attached',
+ message: _message,
+ showIcon: 'exclamation triangle',
+ class: 'warning'
+ })
+ ;
return false;
} else {
return true;
}
$(function() {
- $('body').append($('<div id="warnings" title="{{ _T("Warning")|e("js") }}"><div class="header">{{ _T("Some warnings has been thrown:")|e("js") }}</div><div class="content"><ul></ul><p class="center aligned">{{ _T("Please correct above warnings to continue.") }}</p></div></div>').hide());
-
_bindForm();
-
- _bindCollapse();
-
_initSortable();
- $('#add_category').click(function() {
+ /*$('#add_category').click(function() {
var _fieldsets = $('fieldset[id^=cat_]');
var _cat_iter = _fieldsets.length + 1;
document.location = _url;
_legend.children(':input').focus();
return false;
- });
+ });*/
});
</script>
{% endblock %}