diff --git a/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxFolderTreeController.php b/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxFolderTreeController.php
index c108393cf..6efbb2f84 100644
--- a/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxFolderTreeController.php
+++ b/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxFolderTreeController.php
@@ -71,7 +71,7 @@ public function getTreeAction(Request $request): JsonResponse
'statusCode' => '200',
'status' => 'success',
'tree_type' => $assignation['tree_type'],
- 'folderTree' => $this->twig->render('@RoadizRozier/widgets/tree/rz_tree_wrapper_auto.html.twig', $assignation),
+ 'folderTree' => $this->twig->render('@RoadizRozier/widgets/rz_tree_wrapper_auto.html.twig', $assignation),
]);
}
}
diff --git a/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxNodeTreeController.php b/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxNodeTreeController.php
index 8582a7b16..ff543f4db 100644
--- a/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxNodeTreeController.php
+++ b/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxNodeTreeController.php
@@ -124,7 +124,7 @@ public function getTreeAction(Request $request): JsonResponse
'status' => 'success',
'tree_type' => $assignation['tree_type'],
'linkedTypes' => $linkedTypes,
- 'nodeTree' => trim($this->twig->render('@RoadizRozier/widgets/tree/rz_tree_wrapper_auto.html.twig', $assignation)),
+ 'nodeTree' => trim($this->twig->render('@RoadizRozier/widgets/rz_tree_wrapper_auto.html.twig', $assignation)),
]);
}
}
diff --git a/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxTagTreeController.php b/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxTagTreeController.php
index 18cd24b12..6043bbe57 100644
--- a/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxTagTreeController.php
+++ b/lib/RoadizRozierBundle/src/Controller/Ajax/Tree/AjaxTagTreeController.php
@@ -78,7 +78,7 @@ public function getTreeAction(Request $request): JsonResponse
'statusCode' => '200',
'status' => 'success',
'tree_type' => $assignation['tree_type'],
- 'tagTree' => $this->twig->render('@RoadizRozier/widgets/tree/rz_tree_wrapper_auto.html.twig', $assignation),
+ 'tagTree' => $this->twig->render('@RoadizRozier/widgets/rz_tree_wrapper_auto.html.twig', $assignation),
]);
}
}
diff --git a/lib/RoadizRozierBundle/templates/macros/rz_page_header.html.twig b/lib/RoadizRozierBundle/templates/macros/rz_page_header.html.twig
index 9bcacd5cb..d9620aecf 100644
--- a/lib/RoadizRozierBundle/templates/macros/rz_page_header.html.twig
+++ b/lib/RoadizRozierBundle/templates/macros/rz_page_header.html.twig
@@ -97,14 +97,18 @@
'translationId': translation.id,
'locale': translation.locale
})) %}
+
+ {% set attr = { href: href } %}
+ {% if current == translation.getId %}
+ {% set attr = attr|merge({ 'aria-current': 'page' }) %}
+ {% endif %}
+
{{ rz_link.root({
class: class,
label: translation.preferredLocale,
- attributes: {
- href: href,
- (current == translation.getId) ? aria-current: 'page' : null,
- }
+ attributes: attr,
}) }}
+
{%- endfor -%}
{% if pathAddTranslations is defined and pathAddTranslations %}
{% set class = 'rz-button rz-button-group__button' %}
diff --git a/lib/RoadizRozierBundle/templates/nodes/tree.html.twig b/lib/RoadizRozierBundle/templates/nodes/tree.html.twig
index 8a545eccd..087088056 100644
--- a/lib/RoadizRozierBundle/templates/nodes/tree.html.twig
+++ b/lib/RoadizRozierBundle/templates/nodes/tree.html.twig
@@ -66,12 +66,15 @@
class="rz-tree"
group="nodeTree"
data-entity-type="node"
+ data-stack-tree="true"
data-is-sortable="{{ specificNodeTree.canReorder ? 'true' : 'false' }}"
id="children-stack-{{ specificNodeTree.id ?? node.id ?? 'root' }}"
>
{% include '@RoadizRozier/widgets/nodeTree/nodeTree.html.twig' with {
nodeTree: specificNodeTree,
node: specificNodeTree.getRootNode,
+ isMainTree: false,
+ layout: 'condensed',
} only %}
{% else %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/folderTree/folderTree.html.twig b/lib/RoadizRozierBundle/templates/widgets/folderTree/folderTree.html.twig
index 8cebda70f..43723f5ba 100644
--- a/lib/RoadizRozierBundle/templates/widgets/folderTree/folderTree.html.twig
+++ b/lib/RoadizRozierBundle/templates/widgets/folderTree/folderTree.html.twig
@@ -1,6 +1,7 @@
{%- if folderTree -%}
{% for cfolder in folderTree.folders %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/folderTree/rz_folder_tree_wrapper.html.twig b/lib/RoadizRozierBundle/templates/widgets/folderTree/rz_folder_tree_wrapper.html.twig
deleted file mode 100644
index 2c2e8c099..000000000
--- a/lib/RoadizRozierBundle/templates/widgets/folderTree/rz_folder_tree_wrapper.html.twig
+++ /dev/null
@@ -1,32 +0,0 @@
-{% embed '@RoadizRozier/widgets/rz_tree_wrapper.html.twig' with {
- has_header: mainFolderTree,
- title: 'folderTree'|trans,
- display_translations: mainFolderTree,
- tree: folderTree,
- mainFolderTree: mainFolderTree,
- tree_type: 'folder',
-} only %}
-
- {% block head_button %}
- {% if tree is defined %}
- {{ _self.button({
- icon: 'rz-icon-ri--add-line',
- label: folderTree.getRootFolder == null ? 'add.a.folder'|trans : 'add.child.folder'|trans,
- id: 'foldertree-btn-add',
- attributes: {
- href: folderTree.getRootFolder == null ?
- path('foldersAddPage')
- : path('foldersAddChildPage', { folderId : folderTree.rootFolder.id }),
- }
- }) }}
- {% endif %}
- {% endblock %}
-
- {% block tree_content %}
- {% include '@RoadizRozier/widgets/folderTree/folderTree.html.twig' with {
- folderTree: tree,
- mainFolderTree: mainFolderTree,
- } only %}
- {% endblock %}
-
-{% endembed %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/nodeTree/nodeTree.html.twig b/lib/RoadizRozierBundle/templates/widgets/nodeTree/nodeTree.html.twig
index 6402506a6..0d91348ba 100644
--- a/lib/RoadizRozierBundle/templates/widgets/nodeTree/nodeTree.html.twig
+++ b/lib/RoadizRozierBundle/templates/widgets/nodeTree/nodeTree.html.twig
@@ -16,6 +16,7 @@
"isMainTree": isMainTree,
"level": 0,
'canReorder': nodeTree.canReorder,
+ "layout": layout,
} only %}
{% endfor %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/nodeTree/rz_node_tree_wrapper.html.twig b/lib/RoadizRozierBundle/templates/widgets/nodeTree/rz_node_tree_wrapper.html.twig
deleted file mode 100644
index 14c7230fc..000000000
--- a/lib/RoadizRozierBundle/templates/widgets/nodeTree/rz_node_tree_wrapper.html.twig
+++ /dev/null
@@ -1,45 +0,0 @@
-{% embed '@RoadizRozier/widgets/rz_tree_wrapper.html.twig' with {
- has_header: mainNodeTree,
- title: 'nodeTree'|trans,
- display_translations: mainNodeTree,
- tree: nodeTree,
- mainNodeTree: mainNodeTree,
- linkedTypes: linkedTypes,
- tree_type: 'node',
-} only %}
-
- {% block head_button %}
- {% if tree is defined %}
- {{ _self.button({
- icon: 'rz-icon-ri--add-line',
- label: not tree.rootNode ? 'add.a.node'|trans : 'add.child.node'|trans,
- attributes: {
- href: not tree.rootNode ?
- path('nodesAddPage', { translationId: tree.translation.id })
- : path('nodesAddChildPage', { nodeId : tree.rootNode.id }),
- }
- }) }}
- {% endif %}
- {% endblock %}
-
- {% block after_title %}
- {% import '@RoadizRozier/macros/rz_link.html.twig' as rz_link %}
- {{ rz_link.root({
- icon: 'rz-icon-ri--search-line',
- class: 'rz-aside__root-tree-link',
- attributes: {
- href: path('nodesMainTreePage', { translationId: tree.translation.id }),
- title: 'see_all'|trans,
- }
- }) }}
- {% endblock %}
-
- {% block tree_content %}
- {% include '@RoadizRozier/widgets/nodeTree/nodeTree.html.twig' with {
- nodeTree: tree,
- mainNodeTree: mainNodeTree,
- linkedTypes: linkedTypes,
- } %}
- {% endblock %}
-
-{% endembed %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/nodeTree/singleNode.html.twig b/lib/RoadizRozierBundle/templates/widgets/nodeTree/singleNode.html.twig
index 0e123074d..c6a86d5d1 100644
--- a/lib/RoadizRozierBundle/templates/widgets/nodeTree/singleNode.html.twig
+++ b/lib/RoadizRozierBundle/templates/widgets/nodeTree/singleNode.html.twig
@@ -36,12 +36,12 @@
{% set innerClasses = innerClasses|merge(['rz-tree__item__node--not-visible']) %}
{% endif %}
-
date() %}
{% set icon_class = 'rz-icon-ri--history-line' %}
{% endif %}
+ {% set contextual_menu_id = 'node-contextual-menu-' ~ (isMainTree ? 'main-' : '') ~ node.id %}
{% embed '@RoadizRozier/widgets/rz_tree_item_inner.html.twig' with {
item: node,
has_children: children is defined and children|length > 0,
icon_class: icon_class,
can_reorder: canReorder and not node.isLocked,
- has_selection: nodeTree.isStackTree,
+ has_selection: layout == 'condensed' and not isMainTree and nodeTree.isStackTree,
nodeTree: nodeTree,
- isMainTree: isMainTree
+ isMainTree: isMainTree,
+ contextual_menu_id: contextual_menu_id,
} only %}
{% block icon_content %}
- {%- if not isMainTree and not nodeTree.isStackTree -%}
+ {%- if layout == 'condensed' -%}
{% import '@RoadizRozier/macros/rz_button.html.twig' as rz_button %}
{{ rz_button.root({
@@ -165,7 +166,7 @@
class: 'tree-contextualmenu-button',
attributes: {
'aria-label': 'show.actions'|trans,
- popovertarget: contextual_id ~ '-popover',
+ popovertarget: contextual_menu_id ~ '-popover',
type: 'button',
}
})}}
@@ -194,6 +195,7 @@
"level": level + 1,
'canReorder': (node.childrenOrder == 'position'),
'is_last': loop.last,
+ "layout": layout,
} only %}
{% endfor %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/rz_aside.html.twig b/lib/RoadizRozierBundle/templates/widgets/rz_aside.html.twig
index 0064a42c9..8b6b8a03e 100644
--- a/lib/RoadizRozierBundle/templates/widgets/rz_aside.html.twig
+++ b/lib/RoadizRozierBundle/templates/widgets/rz_aside.html.twig
@@ -1,7 +1,10 @@
-
+{% set default_translation = getAvailableTranslations()|find(t => t.defaultTranslation) %}
+
- {% include '@RoadizRozier/widgets/tree/rz_tree_wrapper_auto.html.twig' with {
- root_classes: ['rz-aside__body'],
- } %}
+ {% include '@RoadizRozier/widgets/rz_tree_wrapper_auto.html.twig' only %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/rz_language_switcher.html.twig b/lib/RoadizRozierBundle/templates/widgets/rz_language_switcher.html.twig
index 5f1965cf4..b21041d3e 100644
--- a/lib/RoadizRozierBundle/templates/widgets/rz_language_switcher.html.twig
+++ b/lib/RoadizRozierBundle/templates/widgets/rz_language_switcher.html.twig
@@ -5,13 +5,13 @@
{%- for translation in translations -%}
- {{ _self.item(translation, tree) }}
+ {{ _self.item(translation, tree, btn_attr) }}
{%- endfor -%}
{% endif %}
-{% macro item(translation, tree) %}
+{% macro item(translation, tree, btn_attr = {}) %}
{% set button_data = {
emphasis: 'tertiary',
@@ -21,7 +21,11 @@
{% if tree is defined %}
{% set button_data = button_data|merge({ selected: translation.id == tree.translation.id }) %}
- {% set button_attr = { 'data-translation-id': translation.id } %}
+ {% set button_attr = {
+ 'data-translation-id': translation.id,
+ 'command': '--update-translation',
+ 'type': 'button',
+ } %}
{% if tree.rootNode is defined %}
{% set button_attr = button_attr|merge({'data-children-parent-node': tree.rootNode.id }) %}
@@ -31,10 +35,12 @@
{% set button_attr = button_attr|merge({'data-filter-tag': tree.tag.id}) %}
{% endif %}
- {% set button_data = button_data|merge({attributes: button_attr}) %}
{% endif %}
{% import "@RoadizRozier/macros/rz_button.html.twig" as rz_button %}
- {{ rz_button.root(button_data) }}
+ {{ rz_button.root(button_data|merge({
+ attributes: button_attr|merge(btn_attr)
+ }))
+ }}
{% endmacro %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/rz_tree_wrapper.html.twig b/lib/RoadizRozierBundle/templates/widgets/rz_tree_wrapper.html.twig
deleted file mode 100644
index eb0304d05..000000000
--- a/lib/RoadizRozierBundle/templates/widgets/rz_tree_wrapper.html.twig
+++ /dev/null
@@ -1,58 +0,0 @@
-{% set type_prefix = tree_type|default('node') %}
-{% set root_classes = ['rz-tree-wrapper', 'tree-widget', type_prefix ~ '-tree-widget'] %}
-
- {% if not tree %}
- {% import "@RoadizRozier/macros/rz_button.html.twig" as rz_button %}
- {{ rz_button.root({
- tagName: 'div',
- label: 'loading'|trans,
- emphasis: 'secondary',
- size: 'md',
- iconClass: 'rz-spinner',
- class: 'rz-aside__loading-button',
- attributes: {
- 'aria-live': 'polite',
- 'role': 'status',
- }
- }) }}
- {% else %}
-
- {% if has_header is defined and has_header %}
-
-
-
-
- {{ title|default('rz_aside.title'|trans) }}
- {% block after_title %}{% endblock %}
-
-
- {% block head_button %}{% endblock %}
-
- {% endif %}
-
- {% if display_translations %}
- {% include '@RoadizRozier/widgets/rz_language_switcher.html.twig' with {
- tree: tree,
- type_prefix: type_prefix,
- classes: ['rz-aside__langs', type_prefix ~ '-tree-langs'],
- } only %}
- {% endif %}
-
- {% set tree_wrapper_classes = ['rz-tree', 'rz-tree--' ~ type_prefix ] %}
- {% set tree_id = tree.id ?? tree.parentNode.id ?? tree.rootTag.id ?? tree.rootFolder.id ?? 'root' %}
-
- {% block tree_content %}{% endblock %}
-
- {% endif %}
-
-
-{% macro button(options) %}
- {% import "@RoadizRozier/macros/rz_button.html.twig" as rz_button %}
- {{ rz_button.root(options|merge({ size: 'sm', class: 'rz-aside__button' })) }}
-{% endmacro %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/rz_tree_wrapper_auto.html.twig b/lib/RoadizRozierBundle/templates/widgets/rz_tree_wrapper_auto.html.twig
new file mode 100644
index 000000000..b6c6e7b39
--- /dev/null
+++ b/lib/RoadizRozierBundle/templates/widgets/rz_tree_wrapper_auto.html.twig
@@ -0,0 +1,114 @@
+{% import "@RoadizRozier/macros/rz_button.html.twig" as rz_button %}
+
+{% set type_prefix = tree_type|default('node') %}
+{% set root_classes = ['rz-tree-wrapper', 'tree-widget', type_prefix ~ '-tree-widget'] %}
+
+
+ {% if not tree %}
+ {{ rz_button.root({
+ tagName: 'div',
+ label: 'loading'|trans,
+ emphasis: 'secondary',
+ size: 'md',
+ iconClass: 'rz-spinner',
+ class: 'rz-aside__loading-button',
+ attributes: {
+ 'aria-live': 'polite',
+ 'role': 'status',
+ }
+ }) }}
+ {% else %}
+
+
+
+ {{-
+ tree_type == 'node'
+ ? 'nodeTree'|trans
+ : tree_type == 'tag'
+ ? 'tagTree'|trans
+ : 'folderTree'|trans
+ -}}
+
+
+ {% set btn_label = null %}
+ {% set btn_href = null %}
+
+ {% if tree_type == 'node' %}
+ {% set btn_label = not tree.rootNode
+ ? 'add.a.node'|trans
+ : 'add.child.node'|trans %}
+ {% set btn_href = not tree.rootNode
+ ? path('nodesAddPage', { translationId: tree.translation.id })
+ : path('nodesAddChildPage', { nodeId: tree.rootNode.id }) %}
+
+ {% elseif tree_type == 'tag' %}
+ {% set btn_label = tree.getRootTag == null
+ ? 'add.a.tag'|trans
+ : 'add.child.tag'|trans %}
+ {% set btn_href = tree.getRootTag == null
+ ? path('tagsAddPage')
+ : path('tagsAddChildPage', { tagId: tree.rootTag.id }) %}
+
+ {% elseif tree_type == 'folder' %}
+ {% set btn_label = tree.getRootFolder == null
+ ? 'add.a.folder'|trans
+ : 'add.child.folder'|trans %}
+ {% set btn_href = tree.getRootFolder == null
+ ? path('foldersAddPage')
+ : path('foldersAddChildPage', { folderId: tree.rootFolder.id }) %}
+ {% endif %}
+
+ {{ rz_button.root({
+ icon: 'rz-icon-ri--add-line',
+ size: 'sm',
+ label: btn_label,
+ class: 'rz-aside__button',
+ attributes: {
+ href: btn_href,
+ }
+ }) }}
+
+
+ {% if mainTree %}
+ {% include '@RoadizRozier/widgets/rz_language_switcher.html.twig' with {
+ tree: tree,
+ type_prefix: type_prefix,
+ classes: ['rz-aside__langs', type_prefix ~ '-tree-langs'],
+ btn_attr: { 'commandfor': 'rz-aside' },
+ } only %}
+ {% endif %}
+
+ {% set tree_wrapper_classes = ['rz-tree', 'rz-tree--' ~ type_prefix ] %}
+ {% set tree_id = tree.id ?? tree.parentNode.id ?? tree.rootTag.id ?? tree.rootFolder.id ?? 'root' %}
+
+ {% if tree_type == 'node' %}
+ {% include '@RoadizRozier/widgets/nodeTree/nodeTree.html.twig' with {
+ nodeTree: tree,
+ isMainTree: not tree.rootNode.id or (isMainTree is defined and isMainTree),
+ linkedTypes: linkedTypes|default(null),
+ layout: 'condensed',
+ } %}
+
+ {% elseif tree_type == 'tag' %}
+ {% include '@RoadizRozier/widgets/tagTree/tagTree.html.twig' with {
+ tagTree: tree,
+ isMainTree: not tree.parentTag.id or (isMainTree is defined and isMainTree),
+ layout: 'condensed',
+ } %}
+
+ {% elseif tree_type == 'folder' %}
+ {% include '@RoadizRozier/widgets/folderTree/folderTree.html.twig' with {
+ folderTree: tree,
+ isMainTree: not tree.parentFolder.id or (isMainTree is defined and isMainTree),
+ layout: 'condensed',
+ } %}
+ {% endif %}
+
+ {% endif %}
+
diff --git a/lib/RoadizRozierBundle/templates/widgets/tagTree/rz_tag_tree_wrapper.html.twig b/lib/RoadizRozierBundle/templates/widgets/tagTree/rz_tag_tree_wrapper.html.twig
deleted file mode 100644
index b9912df4f..000000000
--- a/lib/RoadizRozierBundle/templates/widgets/tagTree/rz_tag_tree_wrapper.html.twig
+++ /dev/null
@@ -1,31 +0,0 @@
-{% embed '@RoadizRozier/widgets/rz_tree_wrapper.html.twig' with {
- has_header: mainTagTree,
- title: 'tagTree'|trans,
- display_translations: mainTagTree,
- tree: tagTree,
- mainTagTree: mainTagTree,
- tree_type: 'tag',
-} only %}
-
- {% block head_button %}
- {% if tree is defined %}
- {{ _self.button({
- icon: 'rz-icon-ri--add-line',
- label: tagTree.getRootTag == null ? 'add.a.tag'|trans : 'add.child.tag'|trans,
- attributes: {
- href: tagTree.getRootTag == null ?
- path('tagsAddPage')
- : path('tagsAddChildPage', { tagId : tagTree.rootTag.id }),
- }
- }) }}
- {% endif %}
- {% endblock %}
-
- {% block tree_content %}
- {% include '@RoadizRozier/widgets/tagTree/tagTree.html.twig' with {
- tagTree: tree,
- mainTagTree: mainTagTree,
- } only %}
- {% endblock %}
-
-{% endembed %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/tagTree/tagTree.html.twig b/lib/RoadizRozierBundle/templates/widgets/tagTree/tagTree.html.twig
index cf0823cd8..80825fe45 100644
--- a/lib/RoadizRozierBundle/templates/widgets/tagTree/tagTree.html.twig
+++ b/lib/RoadizRozierBundle/templates/widgets/tagTree/tagTree.html.twig
@@ -1,6 +1,7 @@
{%- if tagTree -%}
{% for ctag in tagTree.getTags %}
diff --git a/lib/RoadizRozierBundle/templates/widgets/tree/rz_tree_wrapper_auto.html.twig b/lib/RoadizRozierBundle/templates/widgets/tree/rz_tree_wrapper_auto.html.twig
deleted file mode 100644
index 61fc5edc2..000000000
--- a/lib/RoadizRozierBundle/templates/widgets/tree/rz_tree_wrapper_auto.html.twig
+++ /dev/null
@@ -1,101 +0,0 @@
-{% embed '@RoadizRozier/widgets/rz_tree_wrapper.html.twig' with {
- has_header: mainTree,
- title: tree_type == 'node'
- ? 'nodeTree'|trans
- : tree_type == 'tag'
- ? 'tagTree'|trans
- : 'folderTree'|trans,
- display_translations: mainTree,
- tree: tree,
- tree_type: tree_type,
-} only %}
- {# ===================== #}
- {# HEADER BUTTON #}
- {# ===================== #}
- {% block head_button %}
- {% if tree is defined %}
- {% if tree_type == 'node' %}
- {{ _self.button({
- icon: 'rz-icon-ri--add-line',
- label: not tree.rootNode
- ? 'add.a.node'|trans
- : 'add.child.node'|trans,
- attributes: {
- href: not tree.rootNode
- ? path('nodesAddPage', { translationId: tree.translation.id })
- : path('nodesAddChildPage', { nodeId: tree.rootNode.id }),
- }
- }) }}
-
- {% elseif tree_type == 'tag' %}
- {{ _self.button({
- icon: 'rz-icon-ri--add-line',
- label: tree.getRootTag == null
- ? 'add.a.tag'|trans
- : 'add.child.tag'|trans,
- attributes: {
- href: tree.getRootTag == null
- ? path('tagsAddPage')
- : path('tagsAddChildPage', { tagId: tree.rootTag.id }),
- }
- }) }}
-
- {% elseif tree_type == 'folder' %}
- {{ _self.button({
- icon: 'rz-icon-ri--add-line',
- label: tree.getRootFolder == null
- ? 'add.a.folder'|trans
- : 'add.child.folder'|trans,
- id: 'foldertree-btn-add',
- attributes: {
- href: tree.getRootFolder == null
- ? path('foldersAddPage')
- : path('foldersAddChildPage', { folderId: tree.rootFolder.id }),
- }
- }) }}
- {% endif %}
- {% endif %}
- {% endblock %}
-
- {# ===================== #}
- {# AFTER TITLE (node only) #}
- {# ===================== #}
- {% block after_title %}
- {% if tree_type == 'node' and tree is defined %}
- {% import '@RoadizRozier/macros/rz_link.html.twig' as rz_link %}
- {{ rz_link.root({
- icon: 'rz-icon-ri--search-line',
- class: 'rz-aside__root-tree-link',
- attributes: {
- href: path('nodesMainTreePage', { translationId: tree.translation.id }),
- title: 'see_all'|trans,
- }
- }) }}
- {% endif %}
- {% endblock %}
-
- {# ===================== #}
- {# TREE CONTENT #}
- {# ===================== #}
- {% block tree_content %}
- {% if tree_type == 'node' %}
- {% include '@RoadizRozier/widgets/nodeTree/nodeTree.html.twig' with {
- nodeTree: tree,
- isMainTree: true,
- linkedTypes: linkedTypes|default(null),
- } %}
-
- {% elseif tree_type == 'tag' %}
- {% include '@RoadizRozier/widgets/tagTree/tagTree.html.twig' with {
- tagTree: tree,
- isMainTree: true,
- } %}
-
- {% elseif tree_type == 'folder' %}
- {% include '@RoadizRozier/widgets/folderTree/folderTree.html.twig' with {
- folderTree: tree,
- isMainTree: true,
- } %}
- {% endif %}
- {% endblock %}
-{% endembed %}
diff --git a/lib/Rozier/app/@types/rozier.d.ts b/lib/Rozier/app/@types/rozier.d.ts
index e466dc875..59479a846 100644
--- a/lib/Rozier/app/@types/rozier.d.ts
+++ b/lib/Rozier/app/@types/rozier.d.ts
@@ -20,13 +20,6 @@ export default class Rozier {
}
declare global {
- interface RzAsideElement extends HTMLElement {
- bindMainTrees?: () => void
- refreshMainNodeTree?: (translationId?: number) => Promise | void
- refreshMainTagTree?: (translationId?: number) => Promise | void
- refreshMainFolderTree?: (translationId?: number) => Promise | void
- }
-
interface CanvasLoader {
setColor(color: string): void
setShape(shape: string): void
diff --git a/lib/Rozier/app/Rozier.ts b/lib/Rozier/app/Rozier.ts
index 161b25702..662104f17 100644
--- a/lib/Rozier/app/Rozier.ts
+++ b/lib/Rozier/app/Rozier.ts
@@ -1,5 +1,7 @@
import Lazyload from '~/Lazyload'
import VueApp from '~/App'
+import { dispatchSessionToast } from '~/session-message'
+import type RzAside from './custom-elements/RzAside'
/**
* Rozier root entry
@@ -11,6 +13,7 @@ export default class Rozier {
canvasLoader: CanvasLoader | null
lazyload: Lazyload | null = null
vueApp: VueApp | null = null
+ nodeStatuses = null
constructor() {
this.windowWidth = null
@@ -37,25 +40,28 @@ export default class Rozier {
window.addEventListener('requestLoaderHide', () => {
this.canvasLoader?.hide()
})
+ window.addEventListener('requestMessagesRefresh', () => {
+ this.getMessages()
+ })
}
getAsideElement() {
- return document.querySelector('rz-aside') as RzAsideElement | null
+ return document.querySelector('rz-aside') as RzAside | null
}
bindMainTrees() {
- this.getAsideElement()?.bindMainTrees?.()
+ // this.getAsideElement()?.bindMainTrees?.()
}
- refreshMainNodeTree(translationId?: number) {
+ refreshMainNodeTree(translationId?: string) {
return this.getAsideElement()?.refreshMainNodeTree?.(translationId)
}
- refreshMainTagTree(translationId?: number) {
+ refreshMainTagTree(translationId?: string) {
return this.getAsideElement()?.refreshMainTagTree?.(translationId)
}
- refreshMainFolderTree(translationId?: number) {
+ refreshMainFolderTree(translationId?: string) {
return this.getAsideElement()?.refreshMainFolderTree?.(translationId)
}
@@ -76,60 +82,8 @@ export default class Rozier {
this.canvasLoader.setFPS(30)
}
- async fetchSessionMessages() {
- const query = new URLSearchParams({
- _csrf_token: window.RozierConfig.ajaxToken,
- })
- const url =
- window.RozierConfig.routes.ajaxSessionMessages +
- '?' +
- query.toString()
- const response = await fetch(url, {
- method: 'GET',
- headers: {
- 'X-Requested-With': 'XMLHttpRequest',
- Accept: 'application/json',
- },
- })
- const data = (await response.json()) as { messages?: unknown }
- if (!data.messages) {
- return []
- }
- return data.messages
- }
-
- /**
- * Get messages.
- */
async getMessages() {
- const messages = (await this.fetchSessionMessages()) as {
- confirm?: string[]
- error?: string[]
- }
- if (messages.confirm && messages.confirm.length > 0) {
- messages.confirm.forEach((message) => {
- window.dispatchEvent(
- new CustomEvent('pushToast', {
- detail: {
- message: message,
- status: 'success',
- },
- }),
- )
- })
- }
- if (messages.error && messages.error.length > 0) {
- messages.error.forEach((message) => {
- window.dispatchEvent(
- new CustomEvent('pushToast', {
- detail: {
- message: message,
- status: 'danger',
- },
- }),
- )
- })
- }
+ await dispatchSessionToast()
}
resize() {
diff --git a/lib/Rozier/app/custom-elements/RzAside.ts b/lib/Rozier/app/custom-elements/RzAside.ts
index 6f509e532..9205778df 100644
--- a/lib/Rozier/app/custom-elements/RzAside.ts
+++ b/lib/Rozier/app/custom-elements/RzAside.ts
@@ -1,280 +1,171 @@
-import RoadizElement from '~/utils/custom-element/RoadizElement'
import { fadeIn, fadeOut } from '~/utils/animation'
import { sleep } from '~/utils/sleep'
-export default class RzAside extends RoadizElement {
- private onPageShowEnd: () => void
- private onAllNodeTreeChange: () => void
- private onMainTreeRefresh: () => void
- private onBindMainTreesRequest: () => void
- private onAjaxLinkBindRequest: () => void
- private onMessagesRefresh: () => void
- private onLangButtonClick: (event: Event) => void
- private onMainTreeContextMenu: (event: Event) => void
+export default class RzAside extends HTMLElement {
+ private currentTranslationId: string | null = null
+ private entityType: null | string = null
constructor() {
super()
- this.onPageShowEnd = this.handlePageShowEnd.bind(this)
- this.onAllNodeTreeChange = this.handleAllNodeTreeChange.bind(this)
- this.onMainTreeRefresh = this.handleMainTreeRefresh.bind(this)
- this.onBindMainTreesRequest = this.handleBindMainTreesRequest.bind(this)
- this.onAjaxLinkBindRequest = this.handleAjaxLinkBindRequest.bind(this)
- this.onMessagesRefresh = this.handleMessagesRefresh.bind(this)
- this.onLangButtonClick = this.handleLangButtonClick.bind(this)
- this.onMainTreeContextMenu =
- this.maintreeElementNameRightClick.bind(this)
+ this.onPageShowEnd = this.onPageShowEnd.bind(this)
+ this.onCommand = this.onCommand.bind(this)
}
- private get rozier() {
- return window.Rozier
+ private get innerElement() {
+ return this.querySelector('.rz-aside__body') as HTMLElement | null
}
connectedCallback() {
- this.listen(this, 'click', this.onLangButtonClick)
this.refreshAsideMainTree()
- window.addEventListener('pageshowend', this.onPageShowEnd)
- window.addEventListener(
- 'requestAllNodeTreeChange',
- this.onAllNodeTreeChange,
- )
- window.addEventListener(
- 'requestAllNodeTreeRefresh',
- this.onAllNodeTreeChange,
- )
- window.addEventListener(
- 'requestMainTreeRefresh',
- this.onMainTreeRefresh,
- )
- window.addEventListener(
- 'requestBindMainTrees',
- this.onBindMainTreesRequest,
- )
- window.addEventListener(
- 'requestAjaxLinkBind',
- this.onAjaxLinkBindRequest,
- )
- window.addEventListener(
- 'requestMessagesRefresh',
- this.onMessagesRefresh,
+ this.currentTranslationId = this.getAttribute(
+ 'data-default-translation-id',
)
+ window.addEventListener('pageshowend', this.onPageShowEnd)
+ this.addEventListener('command', this.onCommand)
}
disconnectedCallback() {
- super.disconnectedCallback()
-
window.removeEventListener('pageshowend', this.onPageShowEnd)
- window.removeEventListener(
- 'requestAllNodeTreeChange',
- this.onAllNodeTreeChange,
- )
- window.removeEventListener(
- 'requestAllNodeTreeRefresh',
- this.onAllNodeTreeChange,
- )
- window.removeEventListener(
- 'requestMainTreeRefresh',
- this.onMainTreeRefresh,
- )
- window.removeEventListener(
- 'requestBindMainTrees',
- this.onBindMainTreesRequest,
- )
- window.removeEventListener(
- 'requestAjaxLinkBind',
- this.onAjaxLinkBindRequest,
- )
- window.removeEventListener(
- 'requestMessagesRefresh',
- this.onMessagesRefresh,
- )
+ this.removeEventListener('command', this.onCommand)
}
- private handlePageShowEnd() {
- this.refreshAsideMainTree()
- }
-
- private handleAllNodeTreeChange() {
- this.refreshAllNodeTrees()
- window.dispatchEvent(new CustomEvent('requestMessagesRefresh'))
+ onCommand(event: CommandEvent) {
+ switch (event.command) {
+ case '--update-translation':
+ this.onLangButtonClick(event)
+ break
+ }
}
- private handleMainTreeRefresh() {
+ private onPageShowEnd() {
this.refreshAsideMainTree()
}
- private handleMessagesRefresh() {
- this.rozier?.getMessages?.()
- }
-
- private handleBindMainTreesRequest() {
- this.bindMainTrees()
- }
-
- private handleAjaxLinkBindRequest() {
- this.rozier?.lazyload?.bindAjaxLink?.()
- }
-
- private get treeContainer() {
- return this.querySelector('.rz-aside__body') as HTMLElement | null
- }
-
- private handleLangButtonClick(event: Event) {
- const target = (event.target as HTMLElement | null)?.closest('button')
- if (!target || !this.contains(target)) {
+ private onLangButtonClick(event: CommandEvent) {
+ const target = event.source as HTMLButtonElement | undefined
+ if (!target || !this.entityType) {
return
}
+ const translationId = target.getAttribute('data-translation-id')
- const translationIdRaw = target.getAttribute('data-translation-id')
- const translationId = translationIdRaw
- ? parseInt(translationIdRaw, 10)
- : undefined
+ window.dispatchEvent(new CustomEvent('requestLoaderShow'))
- if (target.closest('[data-tree-type="node"]')) {
- window.dispatchEvent(new CustomEvent('requestLoaderShow'))
+ if (this.entityType === 'node') {
this.refreshMainNodeTree(translationId)
- return
- }
-
- if (target.closest('[data-tree-type="folder"]')) {
- window.dispatchEvent(new CustomEvent('requestLoaderShow'))
+ } else if (this.entityType === 'folder') {
this.refreshMainFolderTree(translationId)
- return
- }
-
- if (target.closest('[data-tree-type="tag"]')) {
- window.dispatchEvent(new CustomEvent('requestLoaderShow'))
+ } else if (this.entityType === 'tag') {
this.refreshMainTagTree(translationId)
}
}
- /**
- * Bind main trees
- */
- bindMainTrees() {
- const treeElements = this.querySelectorAll('.tree-element-name')
- treeElements.forEach((element) => {
- element.removeEventListener(
- 'contextmenu',
- this.onMainTreeContextMenu,
- )
- element.addEventListener('contextmenu', this.onMainTreeContextMenu)
- })
+ async refreshMainNodeTree(translationId: string | undefined = undefined) {
+ await this.refreshAsideMainTree(
+ window.RozierConfig.routes?.nodesTreeAjax || null,
+ { translationId },
+ )
}
- /**
- * Main tree element name right click.
- * @return {boolean}
- */
- maintreeElementNameRightClick(event: Event) {
- event.preventDefault()
-
- document
- .querySelectorAll('.tree-contextualmenu')
- .forEach((contextualMenu) => {
- if (contextualMenu.classList.contains('uk-open')) {
- contextualMenu.classList.remove('uk-open')
- }
- })
-
- const target = event.currentTarget as HTMLElement | null
- const contextualMenu = target?.parentElement?.querySelector(
- '.tree-contextualmenu',
+ async refreshMainTagTree(translationId: string | undefined = undefined) {
+ await this.refreshAsideMainTree(
+ window.RozierConfig.routes?.tagsTreeAjax || null,
+ { translationId },
)
- if (contextualMenu) {
- if (!contextualMenu.classList.contains('uk-open')) {
- contextualMenu.classList.add('uk-open')
- } else {
- contextualMenu.classList.remove('uk-open')
- }
- }
-
- return false
}
- /**
- * @param translationId
- */
- refreshAllNodeTrees(translationId?: number) {
- const promises: Array> = []
- promises.push(this.refreshMainNodeTree(translationId))
+ async refreshMainFolderTree(translationId: string | undefined = undefined) {
+ await this.refreshAsideMainTree(
+ window.RozierConfig.routes?.foldersTreeAjax || null,
+ { translationId },
+ )
+ }
- if (this.rozier?.lazyload?.stackNodeTrees?.treeAvailable?.()) {
- promises.push(this.rozier.lazyload.stackNodeTrees.refreshNodeTree())
+ async refreshAsideMainTree(
+ baseUrl: string | null = null,
+ query: Record = {},
+ ) {
+ try {
+ await this.refreshMainTree(baseUrl, query)
+ } catch {
+ console.debug(
+ '[RzAside.refreshAsideMainTree] Retrying in 3 seconds',
+ )
+ await sleep(3000)
+ await this.refreshMainTree(baseUrl, query)
}
- return Promise.all(promises)
+ window.dispatchEvent(new CustomEvent('requestLoaderHide'))
}
- async refreshAsideTreeContent(treeHTML = '') {
+ async refreshTreeContent(treeHTML = '') {
if (!treeHTML) {
- console.warn('No treeHTML provided to refreshAsideTreeContent')
+ console.warn('No treeHTML provided to refreshTreeContent')
return
}
- const treeContainer = this.treeContainer
- if (!treeContainer) {
- console.warn('No tree container found to refreshAsideTreeContent')
+ const innerElement = this.innerElement
+ if (!innerElement) {
+ console.warn('No tree container found to refreshTreeContent')
return
}
- const previousElement = treeContainer.querySelector('.rz-tree-wrapper')
+ const previousElement = innerElement.querySelector('.rz-tree-wrapper')
const temporaryElement = document.createElement('div')
temporaryElement.innerHTML = treeHTML
const newElement = temporaryElement.querySelector('.rz-tree-wrapper')
- await fadeOut(treeContainer)
+ await fadeOut(innerElement)
if (newElement) {
- treeContainer.appendChild(newElement)
+ innerElement.appendChild(newElement)
}
if (previousElement) {
previousElement.remove()
}
- await fadeIn(treeContainer)
+ await fadeIn(innerElement)
+ window.Rozier?.lazyload?.bindAjaxLink?.()
+ }
- this.bindMainTrees()
- this.rozier?.resize?.()
- this.rozier?.lazyload?.bindAjaxLink?.()
+ getDisplayedTreeTranslationId() {
+ return (
+ this.getAttribute('data-translation-id') ||
+ this.innerElement
+ .querySelector('.rz-tree__list')
+ ?.getAttribute('data-translation-id')
+ )
}
async refreshMainTree(
baseUrl?: string | null,
- queryOptions: Record = {},
+ queryOptions: Record = {},
) {
- const treeContainer = this.treeContainer
- if (!treeContainer) {
- return
- }
-
- const currentRootTree = treeContainer.querySelector('.rz-tree-wrapper')
-
- if (currentRootTree && !queryOptions?.translationId) {
- const translationId = currentRootTree.getAttribute(
- 'data-translation-id',
- )
- if (translationId) {
- queryOptions.translationId = translationId
- }
- }
-
- const query = new URLSearchParams({
+ const options = {
_token: window.RozierConfig.ajaxToken,
_action: 'requestMainTree',
url: window.location.pathname,
...queryOptions,
- })
+ }
+ const translationId =
+ queryOptions?.translationId ||
+ this.getDisplayedTreeTranslationId() ||
+ this.currentTranslationId
+
+ if (translationId) {
+ Object.assign(options, { translationId })
+ }
+
+ const query = new URLSearchParams(options)
const fetchUrl =
baseUrl ||
(window.RozierConfig.routes as { treeAjaxGateway?: string })
?.treeAjaxGateway
- if (!fetchUrl) {
- return
- }
+
+ if (!fetchUrl) return
const treeResponse = await fetch(`${fetchUrl}?${query.toString()}`, {
method: 'GET',
headers: {
@@ -296,56 +187,18 @@ export default class RzAside extends RoadizElement {
data?.['tree']
if (data && typeof treeHTML !== 'undefined') {
- const treeTypeId =
- `${data.tree_type || 'node'}-tree` +
- (queryOptions?.translationId
- ? `-${queryOptions?.translationId}`
- : '-main-locale')
-
- if (treeTypeId === treeContainer.getAttribute('data-tree-id')) {
+ // refresh only when new tree will be diferent (translation or type changed)
+ const isSameType = data.tree_type === this.entityType
+ const isSameTranslation =
+ translationId === this.currentTranslationId
+ if (isSameType && isSameTranslation) {
return
}
- this.refreshAsideTreeContent(treeHTML)
- treeContainer.setAttribute('data-tree-id', treeTypeId)
- }
- }
+ await this.refreshTreeContent(treeHTML)
- async refreshAsideMainTree(
- baseUrl: string | null = null,
- query: Record = {},
- ) {
- try {
- await this.refreshMainTree(baseUrl, query)
- } catch {
- console.debug(
- '[RzAside.refreshAsideMainTree] Retrying in 3 seconds',
- )
- await sleep(3000)
- await this.refreshMainTree(baseUrl, query)
+ this.entityType = data.tree_type
+ this.currentTranslationId = translationId
}
-
- window.dispatchEvent(new CustomEvent('requestLoaderHide'))
- }
-
- async refreshMainNodeTree(translationId: number | undefined = undefined) {
- await this.refreshAsideMainTree(
- window.RozierConfig.routes?.nodesTreeAjax || null,
- { translationId },
- )
- }
-
- async refreshMainTagTree(translationId: number | undefined = undefined) {
- await this.refreshAsideMainTree(
- window.RozierConfig.routes?.tagsTreeAjax || null,
- { translationId },
- )
- }
-
- async refreshMainFolderTree(translationId: number | undefined = undefined) {
- await this.refreshAsideMainTree(
- window.RozierConfig.routes?.foldersTreeAjax || null,
- { translationId },
- )
}
}
diff --git a/lib/Rozier/app/custom-elements/RzNodeTreeContextualMenu.ts b/lib/Rozier/app/custom-elements/RzNodeTreeContextualMenu.ts
index c0b328b02..3323b2bab 100644
--- a/lib/Rozier/app/custom-elements/RzNodeTreeContextualMenu.ts
+++ b/lib/Rozier/app/custom-elements/RzNodeTreeContextualMenu.ts
@@ -283,13 +283,11 @@ export default class RzNodeTreeContextualMenu extends HTMLElement {
window.dispatchEvent(new CustomEvent('requestLoaderShow'))
const nodeTreeElement = (event.currentTarget as HTMLElement).closest(
- '.nodetree-element',
+ '.rz-tree__item',
)
const parentNodeId = parseInt(
- nodeTreeElement
- .closest('ul')
- ?.getAttribute('data-parent-node-id') || '',
+ nodeTreeElement.closest('ul')?.getAttribute('data-parent-id') || '',
)
const postData: UpdatePayloadDict = {
diff --git a/lib/Rozier/app/custom-elements/RzTree.ts b/lib/Rozier/app/custom-elements/RzTree.ts
index 5f4095eb8..e75b29ef4 100644
--- a/lib/Rozier/app/custom-elements/RzTree.ts
+++ b/lib/Rozier/app/custom-elements/RzTree.ts
@@ -12,6 +12,8 @@ export default class RzTree extends HTMLElement {
this.sortables = []
this.onSortableChange = this.onSortableChange.bind(this)
this.onCommand = this.onCommand.bind(this)
+ this.onRequestAllNodeTreeChange =
+ this.onRequestAllNodeTreeChange.bind(this)
}
get group() {
@@ -63,13 +65,27 @@ export default class RzTree extends HTMLElement {
}
this.syncCollapsedState()
- this.bindExpandButtons()
+ this.bindExpandButtonsId()
this.addEventListener('command', this.onCommand)
+
+ window.addEventListener(
+ 'requestAllNodeTreeChange',
+ this.onRequestAllNodeTreeChange,
+ )
}
disconnectedCallback() {
this.removeEventListener('command', this.onCommand)
this.destroySortable()
+
+ window.removeEventListener(
+ 'requestAllNodeTreeChange',
+ this.onRequestAllNodeTreeChange,
+ )
+ }
+
+ onRequestAllNodeTreeChange() {
+ this.refreshNodeTree()
}
onCommand(event: CommandEvent) {
@@ -78,6 +94,7 @@ export default class RzTree extends HTMLElement {
this.onToggleChildren(event)
break
case '--quick-add-child-node':
+ // Add child from children-nodes-widget (form) context
this.onQuickAddNode(event)
break
}
@@ -102,10 +119,7 @@ export default class RzTree extends HTMLElement {
}
getRootNodeId() {
- const rootList = this.rootList
- if (!rootList) return null
-
- const rootNodeId = rootList.getAttribute('data-parent-id')
+ const rootNodeId = this.rootList?.getAttribute('data-parent-id')
if (!rootNodeId) return null
const parsedId = parseInt(rootNodeId, 10)
@@ -184,17 +198,26 @@ export default class RzTree extends HTMLElement {
}
}
- async fetchNodeTree(
- rootNodeId: number,
- linkedTypes: string[],
- translationId: number | null = null,
- ) {
- const params = new URLSearchParams({
+ async fetchNodeTree() {
+ const linkedTypes = this.getRootLinkedTypes()
+ const translationId = this.getRootTranslationId()
+
+ const options = {
_token: window.RozierConfig.ajaxToken,
_action: 'requestNodeTree',
- parentNodeId: rootNodeId.toString(),
translationId: translationId ? translationId.toString() : '',
- })
+ }
+
+ if (this.hasAttribute('data-stack-tree')) {
+ Object.assign(options, { stackTree: true })
+ }
+
+ const rootNodeId = this.getRootNodeId()
+ if (!!rootNodeId || rootNodeId === 0) {
+ Object.assign(options, { parentNodeId: rootNodeId.toString() })
+ }
+ const params = new URLSearchParams(options)
+
linkedTypes.forEach((type, i) => {
params.append(`linkedTypes[${i}]`, type)
})
@@ -217,23 +240,20 @@ export default class RzTree extends HTMLElement {
return await response.json()
}
- async refreshNodeTree() {
- const rootNodeId = this.getRootNodeId()
- if (!rootNodeId) {
- console.log('No node-tree available.')
- return
- }
-
- const linkedTypes = this.getRootLinkedTypes()
- const translationId = this.getRootTranslationId()
+ async refreshOtherTrees() {
+ const instances = document.querySelectorAll('rz-tree')
+ const refreshPromises = Array.from(instances)
+ .filter((instance) => instance !== this)
+ .map((instance) => instance.refreshNodeTree())
+ await Promise.all(refreshPromises)
+ }
+ async refreshNodeTree() {
window.dispatchEvent(new CustomEvent('requestLoaderShow'))
+
try {
- const data = await this.fetchNodeTree(
- rootNodeId,
- linkedTypes,
- translationId,
- )
+ const data = await this.fetchNodeTree()
+
if (typeof data.nodeTree !== 'undefined') {
const wrapper = document.createElement('div')
wrapper.innerHTML = data.nodeTree
@@ -266,13 +286,11 @@ export default class RzTree extends HTMLElement {
} else {
this.innerHTML = data.nodeTree
this.rootNode = this.querySelector('[role="tree"]')
- this.bindExpandButtons()
await fadeIn(this)
}
- window.dispatchEvent(new CustomEvent('requestNestablesInit'))
- window.dispatchEvent(new CustomEvent('requestBindMainTrees'))
- window.dispatchEvent(new CustomEvent('requestAjaxLinkBind'))
+ this.bindExpandButtonsId()
+ window.Rozier?.lazyload?.bindAjaxLink?.()
}
} catch (error) {
await this.pushRequestError(error)
@@ -330,7 +348,7 @@ export default class RzTree extends HTMLElement {
this.updateCollapsedState(item, newValue)
}
- bindExpandButtons() {
+ bindExpandButtonsId() {
const buttons = this.querySelectorAll('.rz-tree__item__expand-button')
if (!buttons.length) return
@@ -524,10 +542,12 @@ export default class RzTree extends HTMLElement {
throw response
}
const data = await response.json()
+
const message =
this.entityType === 'node'
? data.responseText || data.detail
: data.responseText
+
window.dispatchEvent(
new CustomEvent('pushToast', {
detail: {
@@ -536,6 +556,8 @@ export default class RzTree extends HTMLElement {
},
}),
)
+
+ await this.refreshOtherTrees()
} catch (response) {
const data = await response.json()
window.dispatchEvent(
diff --git a/lib/Rozier/app/session-message.ts b/lib/Rozier/app/session-message.ts
new file mode 100644
index 000000000..101bbc52f
--- /dev/null
+++ b/lib/Rozier/app/session-message.ts
@@ -0,0 +1,60 @@
+type SessionMessagesResponse = {
+ messages?: {
+ confirm?: string[]
+ error?: string[]
+ }
+}
+
+export async function fetchSessionMessages() {
+ const query = new URLSearchParams({
+ _csrf_token: window.RozierConfig.ajaxToken,
+ })
+
+ const url =
+ window.RozierConfig.routes.ajaxSessionMessages + '?' + query.toString()
+
+ const response = await fetch(url, {
+ method: 'GET',
+ headers: {
+ 'X-Requested-With': 'XMLHttpRequest',
+ Accept: 'application/json',
+ },
+ })
+
+ if (!response.ok) {
+ return null
+ }
+
+ const data = (await response.json()) as SessionMessagesResponse
+ return data?.messages
+}
+
+export async function dispatchSessionToast() {
+ const messages = await fetchSessionMessages()
+ if (!messages) return
+
+ if (messages.confirm && messages.confirm.length > 0) {
+ messages.confirm.forEach((message) => {
+ window.dispatchEvent(
+ new CustomEvent('pushToast', {
+ detail: {
+ message: message,
+ status: 'success',
+ },
+ }),
+ )
+ })
+ }
+ if (messages.error && messages.error.length > 0) {
+ messages.error.forEach((message) => {
+ window.dispatchEvent(
+ new CustomEvent('pushToast', {
+ detail: {
+ message: message,
+ status: 'danger',
+ },
+ }),
+ )
+ })
+ }
+}
diff --git a/templates/admin/article/add.html.twig b/templates/admin/article/add.html.twig
index bc6cccabb..124bcb53d 100644
--- a/templates/admin/article/add.html.twig
+++ b/templates/admin/article/add.html.twig
@@ -7,31 +7,27 @@
{%- endblock -%}
{%- block content_body -%}
-
+
{%- block content_body_before -%}{%- endblock -%}
+
{% form_theme form '@RoadizRozier/forms.html.twig' %}
- {{ form_start(form, {
- 'attr': {
- 'id': 'articles-form',
- 'class': 'rz-form'
- }
- }) }}{{ form_widget(form) }}
-
- {% apply spaceless %}
- {% import "@RoadizRozier/macros/rz_button.html.twig" as rz_button %}
- {{ rz_button.root({
- attributes: {
- type: 'submit',
- 'data-action-save': '#articles-form',
- title: 'articles.form.add'|trans,
- },
- label: 'articles.form.add'|trans,
- emphasis: 'primary',
- icon: 'rz-icon-ri--save-line',
- }) }}
- {% endapply %}
-
+ {{ form_start(form) }}
+ {{ form_widget(form) }}
+ {% import "@RoadizRozier/macros/rz_button.html.twig" as rz_button %}
+ {{ rz_button.root({
+ label: 'articles.form.add'|trans,
+ emphasis: 'primary',
+ color: 'success',
+ onDark: true,
+ icon: 'rz-icon-ri--save-line',
+ attributes: {
+ 'style': 'align-self: flex-start;',
+ 'type': 'submit',
+ }
+ }) }}
+
{{ form_end(form) }}
+
{%- block content_body_after -%}{%- endblock -%}
-
+
{%- endblock -%}