Lists now features a new YAML option collapsed: [true|false] (default: false) and a new UI/UX that allows for collapsing / expanding collection items, allowing to better managing long lists of items. It is advised to always put as first field the most significant one, so that when a list is collapsed it can be still easily browsed.

Reworked List UI to better handle drag & drop sort. To sort it is now required to use the left drag handle (fixes #724)
This commit is contained in:
Djamil Legato
2016-08-01 17:37:31 -07:00
parent b23a194318
commit 352d80e9a3
10 changed files with 95 additions and 23 deletions

View File

@@ -4,8 +4,10 @@
1. [](#improved)
* Get fresh media list for `Controller::getListMedia()` rather that cache so always latest.
* Add translation strings for the new system.force_ssl option
* Reworked List UI to better handle drag & drop sort. To sort it is now required to use the left drag handle [#724](https://github.com/getgrav/grav-plugin-admin/issues/724)
* Lists now features a new YAML option `controls: [top|bottom|both]` (default: bottom) which will display the "Add Item" button at the Top and/or Bottom position relative to the list. When the Top button is pressed, a new item will be added at the beginning of the list, when the Bottom button is pressed, a new item will be appended to the list.
* Lists now features two new YAML options `sortby: [field]` (default: disabled) and `sortby_dir: [asc|desc]` (default: asc) which will display a new Sorting button in the list allowing to automatically reindex the collection based on the given sort field set.
* Lists now features a new YAML option `collapsed: [true|false]` (default: false) and a new UI/UX that allows for collapsing / expanding collection items, allowing to better managing long lists of items. It is advised to always put as first field the most significant one, so that when a list is collapsed it can be still easily browsed.
1. [](#bugfix)
* Fixed issue in Admin favicon URL [#704](https://github.com/getgrav/grav-plugin-admin/issues/704)
* Fixed issue in `selfupgrade` where the package would get downloaded in the wrong destination

View File

@@ -17,7 +17,11 @@ export default class CollectionsField {
list.on('click', '> .collection-actions [data-action="add"]', (event) => this.addItem(event));
list.on('click', '> ul > li > .item-actions [data-action="delete"]', (event) => this.removeItem(event));
list.on('click', '> ul > li > .item-actions [data-action="collapse"]', (event) => this.collapseItem(event));
list.on('click', '> ul > li > .item-actions [data-action="expand"]', (event) => this.expandItem(event));
list.on('click', '> .collection-actions [data-action-sort="date"]', (event) => this.sortItems(event));
list.on('click', '> .collection-actions [data-action="collapse_all"]', (event) => this.collapseItems(event));
list.on('click', '> .collection-actions [data-action="expand_all"]', (event) => this.expandItems(event));
list.on('input', '[data-key-observe]', (event) => this.observeKey(event));
list.find('[data-collection-holder]').each((index, container) => {
@@ -26,6 +30,7 @@ export default class CollectionsField {
container.data('collection-sort', new Sortable(container.get(0), {
forceFallback: false,
handle: '.collection-sort',
animation: 150,
filter: '.CodeMirror, .grav-editor-resizer',
onUpdate: () => this.reindex(container)
@@ -74,6 +79,36 @@ export default class CollectionsField {
if (sortAction.length && items.length <= 1) { sortAction.addClass('hidden'); }
}
collapseItems(event) {
let button = $(event.currentTarget);
let items = $(button.closest('[data-type="collection"]')).find('> ul > [data-collection-item] > .item-actions [data-action="collapse"]');
items.click();
}
collapseItem(event) {
let button = $(event.currentTarget);
let item = button.closest('[data-collection-item]');
button.attr('data-action', 'expand').removeClass('fa-chevron-circle-down').addClass('fa-chevron-circle-right');
item.addClass('collection-collapsed');
}
expandItems(event) {
let button = $(event.currentTarget);
let items = $(button.closest('[data-type="collection"]')).find('> ul > [data-collection-item] > .item-actions [data-action="expand"]');
items.click();
}
expandItem(event) {
let button = $(event.currentTarget);
let item = button.closest('[data-collection-item]');
button.attr('data-action', 'collapse').removeClass('fa-chevron-circle-right').addClass('fa-chevron-circle-down');
item.removeClass('collection-collapsed');
}
sortItems(event) {
let button = $(event.currentTarget);
let sortby = button.data('action-sort');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -702,6 +702,11 @@ form {
}
}
}
.collection-sort {
background: #e9e9e9;
border-right: 1px solid #ddd;
}
}
.form-fieldset {

View File

@@ -435,7 +435,6 @@ textarea.frontmatter {
padding: 0;
> li {
cursor: move;
padding: 1rem;
border-radius: $form-border-radius;
margin: 3px 0;
@@ -446,10 +445,15 @@ textarea.frontmatter {
right: 10px;
top: 4px;
.fa-trash-o {
.fa {
cursor: pointer;
}
}
&.collection-collapsed {
height: 70px;
overflow: hidden;
}
}
&[data-collection-nosort] > li {
@@ -460,6 +464,22 @@ textarea.frontmatter {
.collection-actions {
text-align: right;
}
.collection-sort {
position: absolute;
top: 0;
left: 0;
width: 32px;
bottom: 0;
cursor: move;
.fa {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.form-label.block {

View File

@@ -39,6 +39,10 @@
<div class="form-list-wrapper {{ field.size }}" data-type="collection">
{% if fieldControls in ['top', 'both'] %}
<div class="collection-actions{{ not value|length ? ' hidden' : '' }}">
<button class="button" type="button" data-action="expand_all"
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-down"></i> {{ "PLUGIN_ADMIN.EXPAND_ALL"|e|tu }}</button>
<button class="button" type="button" data-action="collapse_all"
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-right"></i> {{ "PLUGIN_ADMIN.COLLAPSE_ALL"|e|tu }}</button>
{% if field.sortby %}
<button class="button{{ not value|length ? ' hidden' : '' }}" type="button" data-action="sort" data-action-sort="{{ field.sortby }}" data-action-sort-dir="{{ field.sortby_dir|default('asc') }}"
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-sort-amount-{{ field.sortby_dir|default('asc') }}"></i> {{ btnSortLabel|e|tu }} '{{ field.sortby }}'</button>
@@ -54,7 +58,8 @@
{% if field.fields %}
{% for key, val in value %}
{% set itemName = name ? name ~ '.' ~ key : key %}
<li data-collection-item="{{ itemName }}" data-collection-key="{{ key }}">
<li data-collection-item="{{ itemName }}" data-collection-key="{{ key }}" class="{{ field.collapsed ? 'collection-collapsed' : '' }}">
<div class="collection-sort"><i class="fa fa-fw fa-bars"></i></div>
{% for childName, child in field.fields %}
{% if childName starts with '.' %}
{% set childKey = childName|trim('.') %}
@@ -84,7 +89,7 @@
{% endfor %}
<div class="item-actions">
{% if field.sort is not same as(false) %}
<i class="fa fa-bars"></i>
<i class="fa fa-chevron-circle-{{ field.collapsed ? 'right' : 'down' }}" data-action="{{ field.collapsed ? 'expand' : 'collapse' }}"></i>
<br />
{% endif %}
<i class="fa fa-trash-o" data-action="delete"></i>
@@ -95,6 +100,10 @@
</ul>
{% if fieldControls in ['bottom', 'both'] %}
<div class="collection-actions">
<button class="button" type="button" data-action="expand_all"
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-down"></i> {{ "PLUGIN_ADMIN.EXPAND_ALL"|e|tu }}</button>
<button class="button" type="button" data-action="collapse_all"
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-right"></i> {{ "PLUGIN_ADMIN.COLLAPSE_ALL"|e|tu }}</button>
{% if field.sortby %}
<button class="button{{ not value|length ? ' hidden' : '' }}" type="button" data-action="sort" data-action-sort="{{ field.sortby }}" data-action-sort-dir="{{ field.sortby_dir|default('asc') }}"
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-sort-amount-{{ field.sortby_dir|default('asc') }}"></i> {{ btnSortLabel|e|tu }} '{{ field.sortby }}'</button>
@@ -107,6 +116,7 @@
{%- set itemName = name ? name ~ '.*' : '*' -%}
<div style="display: none;" data-collection-template="new" data-collection-template-html="{%- filter replace({' ': ' ', '\n': ' '})|e('html_attr') -%}
<li data-collection-item="{{ itemName }}">
<div class="collection-sort"><i class="fa fa-fw fa-bars"></i></div>
{%- if field.fields -%}
{%- for childName, child in field.fields -%}
{%- if childName starts with '.' -%}
@@ -134,7 +144,7 @@
{%- endfor %}
<div class="item-actions">
{% if field.sort is not same as(false) %}
<i class="fa fa-bars"></i>
<i class="fa fa-chevron-circle-down" data-action="collapse"></i>
<br />
{% endif %}
<i class="fa fa-trash-o" data-action="delete"></i>