Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(admin/twig): json menu nested copy/paste functionality #1033

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

<div class="json-menu-nested-component" id="{{ id }}" data-hash="{{ hash }}" {% if config.activeItemId %}data-active-item-id="{{ config.activeItemId }}"{% endif %}>
<div class="jmn-node-loading"><i class="fa fa-cog fa-spin fa-3x fa-fw"></i></div>
{{ template.block('jmn_layout_top', _context)|raw }}
<div class="jmn-top"></div>
<div class="jmn-wrapper">
{{ template.block('_jmn_columns', _context)|raw }}
<div class="jmn-header">{{ template.block('jmn_columns', _context)|raw }}</div>
<div id="{{- "tree-#{id}" -}}" class="jmn-tree jmn-node jmn-sortable" data-id="{{ config.jsonMenuNested.id }}" data-types="{{ config.nodes.types('_root')|json_encode|e('html_attr') }}"></div>
</div>
{{ template.block('jmn_layout_footer', _context)|raw }}
</div>
<div class="jmn-footer"></div>
</div>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% trans_default_domain 'EMSCoreBundle' %}
{%- trans_default_domain 'EMSCoreBundle' -%}
{# @var config \EMS\CoreBundle\Core\Component\JsonMenuNested\Config\JsonMenuNestedConfig #}
{# @var column \EMS\CoreBundle\Core\Component\JsonMenuNested\Config\JsonMenuNestedColumn #}
{# @var template \EMS\CoreBundle\Core\Component\JsonMenuNested\Template\JsonMenuNestedTemplate #}
Expand All @@ -8,32 +8,30 @@
{# @var node \EMS\CoreBundle\Core\Component\JsonMenuNested\Config\JsonMenuNestedNode #}

{%- block jmn_layout_top -%}
<div class="jmn-top">
{{ template.block('jmn_title', _context)|raw }}
{{ template.block('jmn_actions', _context)|raw }}
</div>
<div>{{ template.block('jmn_title', _context)|raw }}</div>
<div>{{ template.block('jmn_actions', _context)|raw }}</div>
{%- endblock jmn_layout_top -%}

{%- block jmn_layout_footer -%}{% endblock jmn_layout_footer %}

{%- block jmn_title -%}{%- endblock jmn_title -%}

{%- block jmn_actions -%}
{% set dropDown = 'left' %}
{%- set dropDown = dropDown|default('right') -%}
{%- set node = config.nodes.root -%}
{{ template.block('jmn_button_add', _context)|raw }}
{{ template.block('jmn_button_more', _context)|raw }}
{%- endblock jmn_actions -%}

{%- block _jmn_columns -%}
<div class="jmn-header">
{% for column in config.columns %}
<div class="jmn-column {{ "jmn-column-#{column.name}" }}" style="{{ column.width ? "width:#{column.width}px;" }}" >
{%- if template.hasBlock("jmn_column_#{column.name}") -%}
{{ template.block("jmn_column_#{column.name}", _context)|raw }}
{%- endif -%}
</div>
{% endfor %}
</div>
{%- endblock _jmn_columns -%}
{%- block jmn_columns -%}
{% for column in config.columns %}
<div class="jmn-column {{ "jmn-column-#{column.name}" }}" style="{{ column.width ? "width:#{column.width}px;" }}" >
{%- if template.hasBlock("jmn_column_#{column.name}") -%}
{{ template.block("jmn_column_#{column.name}", _context)|raw }}
{%- endif -%}
</div>
{% endfor %}
{%- endblock jmn_columns -%}

{% block jmn_render %}
{% with { 'menu': menu } %}{{ template.block('jmn_items', _context)|raw }}{% endwith %}
Expand Down Expand Up @@ -112,33 +110,25 @@
<button class="jmn-btn-view" data-modal-size="{{- buttonModalSize|default('md') -}}">{{- buttonLabel|default('View') -}}</button>
{%- endblock jmn_button_item_view -%}

{%- block jmn_button_item_more -%}
{%- set menuMoreItems = menuMoreItems|default([
'jmn_button_item_view',
'jmn_button_item_edit',
'jmn_button_copy',
'jmn_button_paste',
'jmn_button_item_delete'
]) -%}
{{ template.block('jmn_button_more', _context)|raw }}
{%- endblock jmn_button_item_more -%}

{%- block jmn_button_item_add -%}
<button class="jmn-btn-add" data-add="{{ addNode.id }}" data-modal-size="{{- buttonModalSize|default('md') -}}">
{% if addNode.icon %}<i class="{{ addNode.icon }}"></i>{% endif %}
{{- buttonLabel|default("New #{addNode.label}") -}}
</button>
{%- endblock jmn_button_item_add -%}

{%- block jmn_button_item_more -%}
{% set menuMore = template.block('jmn_button_item_more_menu', _context)|raw %}
{% if menuMore|length > 0 %}
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-sm btn-default dropdown-toggle jmn-dropdown-more" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
<ul class="dropdown-menu pull-right">
{{ menuMore|raw }}
</ul>
</div>
{% endif %}
{%- endblock jmn_button_item_more -%}

{%- block jmn_button_item_more_menu -%}
<li>{{ template.block('jmn_button_item_view', _context)|raw }}</li>
<li>{{ template.block('jmn_button_item_edit', _context)|raw }}</li>
<li>{{ template.block('jmn_button_item_delete', _context)|raw }}</li>
{%- endblock jmn_button_item_more_menu -%}

{%- block jmn_button_add -%}
{% set node = node|default(config.nodes.root) %}
{% set addNodes = config.nodes.children(node) %}
{% set addMenu = template.block('jmn_button_add_menu', _context)|raw %}
{% if addNodes|length > 0 and addMenu|length > 0 %}
Expand All @@ -154,11 +144,53 @@
{%- endblock jmn_button_add -%}

{%- block jmn_button_add_menu -%}
{% for addNode in addNodes|default([]) %}
<li>{{ template.block('jmn_button_item_add', _context)|raw }}</li>
{% endfor %}
{%- for addNode in addNodes|default([]) -%}
{%- set blockButtonItemAdd = template.block('jmn_button_item_add', _context)|raw -%}
{%- if blockButtonItemAdd|length > 0 -%}
<li>{{ template.block('jmn_button_item_add', _context)|raw }}</li>
{%- endif -%}
{%- endfor -%}
{%- endblock jmn_button_add_menu -%}

{%- block jmn_button_more -%}
{%- set menuMoreItems = menuMoreItems|default([
'jmn_button_copy',
'jmn_button_paste',
]) -%}
{% set menuMore = template.block('jmn_button_more_menu', _context)|raw %}
{% if menuMore|length > 0 %}
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-sm btn-default dropdown-toggle jmn-dropdown-more" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
<ul class="{{ html_classes('dropdown-menu', { 'pull-right': (dropDown|default('right') == 'right') }) }}">
{{ menuMore|raw }}
</ul>
</div>
{% endif %}
{%- endblock jmn_button_more -%}

{%- block jmn_button_more_menu -%}
{%- for menuMoreItem in menuMoreItems -%}
{%- set blockMenuMoreItem = template.block(menuMoreItem, _context)|raw -%}
{%- if blockMenuMoreItem|length > 0 -%}
<li>{{ blockMenuMoreItem|raw }}</li>
{%- endif -%}
{%- endfor -%}
{%- endblock jmn_button_more_menu -%}

{%- block jmn_button_copy -%}
<button class="jmn-btn-copy">{{- buttonLabel|default(node == config.nodes.root ? 'Copy all' : 'Copy') -}}</button>
{%- endblock jmn_button_copy -%}

{%- block jmn_button_paste -%}
{%- if render.copyItem -%}
{%- set rootPaste = node == config.nodes.root and render.copyItem.type == config.nodes.root.type -%}
{%- set itemPaste = render.copyItem.type in config.nodes.children(node)|keys -%}
{%- if rootPaste or itemPaste -%}
<button class="jmn-btn-paste">{{- buttonLabel|default('Paste') -}}</button>
{%- endif -%}
{%- endif -%}
{%- endblock jmn_button_paste -%}

{%- block jmn_modal_title -%}
{% set modalTitle = modalTitle|default("#{action|capitalize} #{node.label|default}") %}
{% if node.icon|default(false) %}<i class="{{ node.icon }}"></i>&nbsp;{% endif %}
Expand Down
37 changes: 35 additions & 2 deletions EMS/common-bundle/src/Json/JsonMenuNested.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace EMS\CommonBundle\Json;

use EMS\CommonBundle\Common\PropertyAccess\PropertyAccessor;
use EMS\Helpers\Standard\Base64;
use EMS\Helpers\Standard\Json;
use Ramsey\Uuid\Uuid;
Expand All @@ -15,7 +16,7 @@
final class JsonMenuNested implements \IteratorAggregate, \Countable, \Stringable
{
private string $id;
private readonly string $type;
private string $type;
private string $label;
/** @var array<mixed> */
private array $object;
Expand Down Expand Up @@ -204,7 +205,20 @@ public function search(string $propertyPath, string $value, ?string $type = null

public function changeId(): JsonMenuNested
{
$this->id = Uuid::uuid4()->toString();
if ('_root' !== $this->id) {
$this->id = Uuid::uuid4()->toString();
}

return $this;
}

public function changeIds(): JsonMenuNested
{
$this->changeId();

foreach ($this->getIterator() as $child) {
$child->changeId();
}

return $this;
}
Expand Down Expand Up @@ -246,6 +260,11 @@ public function getType(): string
return $this->type;
}

public function setType(string $type): void
{
$this->type = $type;
}

public function getLabel(): string
{
return $this->label;
Expand Down Expand Up @@ -411,6 +430,20 @@ public function breadcrumb(string $uid, bool $reverseOrder = false): iterable
yield from $this->yieldBreadcrumb($uid, $this->children, $reverseOrder);
}

/**
* @param string[] $paths
*/
public function clear(array $paths): void
{
$propertyAccessor = PropertyAccessor::createPropertyAccessor();

foreach ($paths as $path) {
$propertyAccessor->setValue($this->object, $path, null);
}

$this->object = \array_filter($this->object);
}

/**
* @param JsonMenuNested[] $menu
*
Expand Down
8 changes: 6 additions & 2 deletions EMS/common-bundle/tests/Unit/Json/JsonMenuNestedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ public function testHasChild()
public function testChangeId()
{
$this->assertEquals('_root', $this->jsonMenuNested1->getId());
$this->jsonMenuNested1->changeId();
$this->assertNotEquals('_root', $this->jsonMenuNested1->getId());
$player1 = $this->jsonMenuNested1->getItemById('c7b74edf-5cd1-4af8-a5f0-2ae8fdcc1540');

$this->jsonMenuNested1->changeIds();

$this->assertEquals('_root', $this->jsonMenuNested1->getId());
$this->assertNotEquals('c7b74edf-5cd1-4af8-a5f0-2ae8fdcc1540', $player1->getId());
}

public function testPathMap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: var(--jmn-gap);
}

.jmn-wrapper {
Expand Down
Loading
Loading