mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2025-11-02 03:16:11 +01:00
Merge branch 'feature/ordering-refactor' into develop
# Conflicts: # themes/grav/css-compiled/preset.css # themes/grav/css-compiled/preset.css.map
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
## 03/xx/2017
|
||||
|
||||
1. [](#new)
|
||||
* Completely revamped Page Ordering. Will only reorder with folder-prefix enabled. Can now reorder all siblings.
|
||||
* Improved `range` form field with touch and counter support [#1016](https://github.com/getgrav/grav-plugin-admin/pull/1016)
|
||||
1. [](#bugfix)
|
||||
* Cleanup package files via GPM install to make them more windows-friendly [#1361](https://github.com/getgrav/grav/pull/1361)
|
||||
|
||||
@@ -246,6 +246,18 @@ form:
|
||||
title: Notifications
|
||||
underline: true
|
||||
|
||||
notifications.feed:
|
||||
type: toggle
|
||||
label: Feed Notifications
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
validate:
|
||||
type: bool
|
||||
help: Display feed-based notifications
|
||||
|
||||
notifications.dashboard:
|
||||
type: toggle
|
||||
label: Dashboard Notifications
|
||||
|
||||
@@ -496,9 +496,6 @@ class AdminController extends AdminBaseController
|
||||
$obj = $obj->move($parent);
|
||||
$this->preparePage($obj, false, $obj->language());
|
||||
|
||||
// Reset slug and route. For now we do not support slug twig variable on save.
|
||||
$obj->slug($original_slug);
|
||||
|
||||
try {
|
||||
$obj->validate();
|
||||
} catch (\Exception $e) {
|
||||
@@ -514,6 +511,10 @@ class AdminController extends AdminBaseController
|
||||
$obj->order($original_order + 1);
|
||||
}
|
||||
|
||||
if (isset($data['order']) && !empty($data['order'])) {
|
||||
$reorder = explode(',', $data['order']);
|
||||
}
|
||||
|
||||
// add or remove numeric prefix based on ordering value
|
||||
if (isset($data['ordering'])) {
|
||||
if ($data['ordering'] && !$obj->order()) {
|
||||
@@ -1773,12 +1774,17 @@ class AdminController extends AdminBaseController
|
||||
{
|
||||
$input = (array)$this->data;
|
||||
|
||||
if (isset($input['order'])) {
|
||||
$order = max(0,
|
||||
((int)isset($input['order']) && $input['order']) ? $input['order'] : $page->value('order'));
|
||||
// if (isset($input['folder']) && ) {
|
||||
// $order = $page->value('order');
|
||||
// $ordering = $order ? sprintf('%02d.', $order) : '';
|
||||
// $slug = empty($input['folder']) ? $page->value('folder') : (string)$input['folder'];
|
||||
// $page->folder($ordering . $slug);
|
||||
// }
|
||||
|
||||
if ($input['folder'] != $page->value('folder')) {
|
||||
$order = $page->value('order');
|
||||
$ordering = $order ? sprintf('%02d.', $order) : '';
|
||||
$slug = empty($input['folder']) ? $page->value('folder') : (string)$input['folder'];
|
||||
$page->folder($ordering . $slug);
|
||||
$page->folder($ordering . $input['folder']);
|
||||
}
|
||||
|
||||
if (isset($input['name']) && !empty($input['name'])) {
|
||||
|
||||
@@ -541,6 +541,7 @@ PLUGIN_ADMIN:
|
||||
ORDERING_DISABLED_BECAUSE_PARENT_SETTING_ORDER: "Parent setting order, ordering disabled"
|
||||
ORDERING_DISABLED_BECAUSE_PAGE_NOT_VISIBLE: "Page is not visible, ordering disabled"
|
||||
ORDERING_DISABLED_BECAUSE_TOO_MANY_SIBLINGS: "Ordering via the admin is unsupported because there are more than 200 siblings"
|
||||
ORDERING_DISABLED_BECAUSE_PAGE_NO_PREFIX: "Page ordering is disabled because <strong>Folder Numeric Prefix</strong> is not enabled"
|
||||
CANNOT_ADD_MEDIA_FILES_PAGE_NOT_SAVED: "NOTE: You cannot add media files until you save the page. Just click 'Save' on top"
|
||||
CANNOT_ADD_FILES_PAGE_NOT_SAVED: "NOTE: Page must be saved before you can upload files to it."
|
||||
DROP_FILES_HERE_TO_UPLOAD: "Drop your files here or <strong>click in this area</strong>"
|
||||
@@ -656,4 +657,4 @@ PLUGIN_ADMIN:
|
||||
ZIP_PACKAGE_NOT_FOUND: "ZIP package could not be found"
|
||||
GPM_OFFICIAL_ONLY: "Official GPM Only"
|
||||
GPM_OFFICIAL_ONLY_HELP: "Only allow direct installs from the official GPM repository only."
|
||||
NO_CHILD_TYPE: "No child type for this rawroute"
|
||||
NO_CHILD_TYPE: "No child type for this rawroute"
|
||||
|
||||
@@ -3,18 +3,42 @@ import Sortable from 'sortablejs';
|
||||
import PageFilters, { Instance as PageFiltersInstance } from './filter';
|
||||
import './page';
|
||||
|
||||
const pad = (n, s) => (`000${n}`).substr(-s);
|
||||
|
||||
// Pages Ordering
|
||||
let Ordering = null;
|
||||
let orderingElement = $('#ordering');
|
||||
if (orderingElement.length) {
|
||||
Ordering = new Sortable(orderingElement.get(0), {
|
||||
filter: '.ignore',
|
||||
onUpdate: function(event) {
|
||||
onUpdate: function() {
|
||||
/* Old single page index behavior
|
||||
|
||||
let item = $(event.item);
|
||||
let index = orderingElement.children().index(item) + 1;
|
||||
$('[data-order]').val(index);
|
||||
*/
|
||||
|
||||
let indexes = [];
|
||||
orderingElement.children().each((index, item) => {
|
||||
item = $(item);
|
||||
indexes.push(item.data('id'));
|
||||
item.find('.page-order').text(`${pad(index + 1, 2)}.`);
|
||||
});
|
||||
|
||||
$('[data-order]').val(indexes.join(','));
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('input', '[name="data[folder]"]', (event) => {
|
||||
const target = $(event.currentTarget);
|
||||
const activeOrder = $('[data-id][data-active-id]');
|
||||
|
||||
activeOrder.data('id', target.val());
|
||||
|
||||
Ordering.options.onUpdate();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
2
themes/grav/css-compiled/preset.css
vendored
2
themes/grav/css-compiled/preset.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
themes/grav/css-compiled/template.css
vendored
2
themes/grav/css-compiled/template.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
themes/grav/js/admin.min.js
vendored
4
themes/grav/js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -796,10 +796,8 @@ form {
|
||||
}
|
||||
|
||||
.form-order-wrapper {
|
||||
.note {
|
||||
background: inherit;
|
||||
}
|
||||
ul#ordering {
|
||||
ul.orderable {
|
||||
|
||||
li {
|
||||
border: 1px solid $form-border;
|
||||
background: lighten($content-bg, 2%);
|
||||
@@ -809,6 +807,15 @@ form {
|
||||
background: $form-field-bg;
|
||||
color: $form-field-text;
|
||||
}
|
||||
|
||||
&[data-active-id] {
|
||||
border-color: $form-field-text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.disabled li {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +434,12 @@ textarea.frontmatter {
|
||||
|
||||
// Sortables
|
||||
.form-order-wrapper {
|
||||
ul#ordering {
|
||||
|
||||
.notice {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
ul.orderable {
|
||||
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
@@ -455,6 +460,10 @@ textarea.frontmatter {
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
{% set siblings = data.parent.children.visible %}
|
||||
{% set siblings = data.parent.children %}
|
||||
{% set canOrder = data.order %}
|
||||
|
||||
<div class="form-field grid pure-g">
|
||||
<div class="form-label block size-1-3 pure-u-1-3">
|
||||
@@ -14,25 +15,33 @@
|
||||
</div>
|
||||
<div class="form-data block size-2-3 pure-u-2-3">
|
||||
<div class="form-order-wrapper {{ field.size }}">
|
||||
{% set canReorder = not data.parent.header.content.items and data.visible %}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
data-order
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
value="{{ canReorder ? value : '' }}" />
|
||||
{% if data.parent.header.content.items %}
|
||||
<span class="note">{{ "PLUGIN_ADMIN.ORDERING_DISABLED_BECAUSE_PARENT_SETTING_ORDER"|tu }}</span>
|
||||
{% elseif not data.visible %}
|
||||
<span class="note">{{ "PLUGIN_ADMIN.ORDERING_DISABLED_BECAUSE_PAGE_NOT_VISIBLE"|tu }}</span>
|
||||
{% if not canOrder %}
|
||||
<div class="notice">{{ "PLUGIN_ADMIN.ORDERING_DISABLED_BECAUSE_PAGE_NO_PREFIX"|tu|raw }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if siblings|length < 200 %}
|
||||
<ul id="ordering" class="{{ field.classes }}">
|
||||
{% for page in siblings %}
|
||||
<li class="{% if page.order == value and canReorder %}drag-handle{% else %}ignore{% endif %}" data-id="{{ page.slug }}">{{ page.title|e }}</li>
|
||||
{% set sortable_count = 0 %}
|
||||
<ul id="ordering" class="orderable {{ field.classes }}">
|
||||
{% for page in siblings if page.order %}
|
||||
<li class="drag-handle" data-id="{{ page.slug }}" {{ page.slug == data.slug ? 'data-active-id' : ''}}><span class="page-order">{{ page.order }}</span> {{ page.title|e }} <a href="{{ getPageUrl(page) }}"><i class="fa fa-external-link"></i></a></li>
|
||||
{% set sortable_count = loop.index %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if sortable_count < siblings|length %}
|
||||
<label>Unsortable Pages</label>
|
||||
<ul class="orderable disabled">
|
||||
{% for page in siblings if not page.order %}
|
||||
<li {{ page.slug == data.slug ? 'data-active-id' : ''}}>{{ page.title|e }} <a href="{{ getPageUrl(page) }}"><i class="fa fa-external-link"></i></a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="note">{{ "PLUGIN_ADMIN.ORDERING_DISABLED_BECAUSE_TOO_MANY_SIBLINGS"|tu }}</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -53,11 +53,11 @@
|
||||
{% set warn = twig_vars['warn'] %}
|
||||
{% set uri = twig_vars['uri'] %}
|
||||
|
||||
{% if '@self' in page.header.content.items and page.header.content.order.by %}
|
||||
{% set pcol = page.children().order(page.header.content.order.by, page.header.content.order.dir) %}
|
||||
{% else %}
|
||||
{#{% if '@self' in page.header.content.items and page.header.content.order.by %}#}
|
||||
{#{% set pcol = page.children().order(page.header.content.order.by, page.header.content.order.dir) %}#}
|
||||
{#{% else %}#}
|
||||
{% set pcol = page.children() %}
|
||||
{% endif %}
|
||||
{#{% endif %}#}
|
||||
|
||||
{% for p in pcol %}
|
||||
{% set description = (not p.page ? "PLUGIN_ADMIN.FOLDER"|tu ~ ' • ' : "PLUGIN_ADMIN.PAGE"|tu ~ ' • ') ~
|
||||
@@ -65,12 +65,14 @@
|
||||
(p.routable ? "PLUGIN_ADMIN.ROUTABLE"|tu ~ ' • ' : "PLUGIN_ADMIN.NON_ROUTABLE"|tu ~ ' • ') ~
|
||||
(p.visible ? "PLUGIN_ADMIN.VISIBLE"|tu ~ ' • ' : "PLUGIN_ADMIN.NON_VISIBLE"|tu ~ ' • ') ~
|
||||
(p.published ? "PLUGIN_ADMIN.PUBLISHED"|tu ~ ' • ' : "PLUGIN_ADMIN.NON_PUBLISHED"|tu ~ ' • ') %}
|
||||
{% set page_route = p.rawRoute|trim('/') %}
|
||||
{% if p.language and p.language != admin_lang %}
|
||||
{% set page_url = base_url_simple ~ '/' ~ p.language ~ '/' ~ admin_route ~ '/pages/' ~ page_route %}
|
||||
{% else %}
|
||||
{% set page_url = base_url ~ '/pages/' ~ page_route %}
|
||||
{% endif %}
|
||||
{#{% set page_route = p.rawRoute|trim('/') %}#}
|
||||
{#{% if p.language and p.language != admin_lang %}#}
|
||||
{#{% set page_url = base_url_simple ~ '/' ~ p.language ~ '/' ~ admin_route ~ '/pages/' ~ page_route %}#}
|
||||
{#{% else %}#}
|
||||
{#{% set page_url = base_url ~ '/pages/' ~ page_route %}#}
|
||||
{#{% endif %}#}
|
||||
|
||||
{% set page_url = getPageUrl(p) %}
|
||||
|
||||
<li class="page-item" data-nav-id="{{ p.route }}">
|
||||
<div class="row">
|
||||
|
||||
@@ -45,6 +45,30 @@ class AdminTwigExtension extends \Twig_Extension
|
||||
];
|
||||
}
|
||||
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('getPageUrl', [$this, 'getPageUrl'], ['needs_context' => true]),
|
||||
];
|
||||
}
|
||||
|
||||
public function getPageUrl($context, $page)
|
||||
{
|
||||
$page_route = trim($page->rawRoute(), '/');
|
||||
$page_lang = $page->language();
|
||||
$base_url = $context['base_url'];
|
||||
$base_url_simple = $context['base_url_simple'];
|
||||
$admin_lang = Grav::instance()['session']->admin_lang ?: 'en';
|
||||
|
||||
if ($page_lang && $page_lang != $admin_lang) {
|
||||
$page_url = $base_url_simple . '/' . $page_lang . '/' . $context['admin_route'] . '/pages/' . $page_route;
|
||||
} else {
|
||||
$page_url = $base_url . '/pages/' . $page_route;
|
||||
}
|
||||
|
||||
return $page_url;
|
||||
}
|
||||
|
||||
public function tuFilter()
|
||||
{
|
||||
$args = func_get_args();
|
||||
|
||||
Reference in New Issue
Block a user