diff --git a/assets/js/admin/components/file-manager/FileIcon.vue b/assets/js/admin/components/file-manager/FileIcon.vue
index f29c38d..7769928 100644
--- a/assets/js/admin/components/file-manager/FileIcon.vue
+++ b/assets/js/admin/components/file-manager/FileIcon.vue
@@ -54,6 +54,7 @@ export default {
}
if (['image/png', 'image/jpg', 'image/jpeg', 'image/gif'].indexOf(this.mime) === -1) {
+ this.thumbnail = null
return
}
diff --git a/assets/js/admin/components/file-manager/Files.vue b/assets/js/admin/components/file-manager/Files.vue
index bb10d01..edc575e 100644
--- a/assets/js/admin/components/file-manager/Files.vue
+++ b/assets/js/admin/components/file-manager/Files.vue
@@ -5,6 +5,11 @@
@@ -200,7 +205,8 @@ export default {
files: [],
parent: null,
modalUrl: null,
- ajax: 0
+ ajax: 0,
+ isLoading: false
}
},
methods: {
@@ -266,17 +272,22 @@ export default {
},
refresh () {
const that = this
+ this.isLoading = true
+ this.files = []
+ this.directories = []
axios.get(Routing.generate('admin_file_manager_api_directory', {
directory: that.directory,
context: that.context,
- ajax: this.ajax
+ ajax: this.ajax,
+ time: Date.now(),
}))
.then((response) => {
that.buildBreadcrum(response.data.breadcrumb)
that.parent = response.data.parent
that.directories = response.data.directories
that.files = response.data.files
+ that.isLoading = false
const query = new URLSearchParams(window.location.search)
query.set('path', that.directory)
diff --git a/assets/js/admin/modules/file-picker.js b/assets/js/admin/modules/file-picker.js
index 5bf5b41..1686ffb 100644
--- a/assets/js/admin/modules/file-picker.js
+++ b/assets/js/admin/modules/file-picker.js
@@ -64,8 +64,19 @@ module.exports = function () {
fileManagerBrowser((value) => {
value = value.replace(/^\//, '')
- picker.parent('.form-filepicker-container').find('input.form-filepicker-picker').val(value)
+ picker.parents('.form-filepicker-container').find('input.form-filepicker-picker').val(value)
input.val(value)
})
})
+
+ $('body').on('click', '.form-filepicker-reset', (e) => {
+ e.preventDefault()
+
+ const button = $(e.target)
+ const id = '#' + button.attr('data-target')
+ const input = $(id)
+
+ input.val('')
+ button.parents('.form-filepicker-container').find('input.form-filepicker-picker').val('')
+ })
}
diff --git a/assets/js/admin/modules/modal.js b/assets/js/admin/modules/modal.js
index 4cae714..8afb28a 100644
--- a/assets/js/admin/modules/modal.js
+++ b/assets/js/admin/modules/modal.js
@@ -25,8 +25,15 @@ const openModal = function (url) {
module.exports = function () {
let click = 0
+ const body = $('body')
- $('body').on('click', '*[data-modal]', (e) => {
+ body.on('hidden.bs.modal', '.modal', (e) => {
+ if ($('.modal.show').length) {
+ $('body').addClass('modal-open')
+ }
+ })
+
+ body.on('click', '*[data-modal]', (e) => {
e.preventDefault()
e.stopPropagation()
diff --git a/core/Controller/Site/PageAdminController.php b/core/Controller/Site/PageAdminController.php
index 18187ae..b6b73ff 100644
--- a/core/Controller/Site/PageAdminController.php
+++ b/core/Controller/Site/PageAdminController.php
@@ -15,6 +15,8 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
+use App\Core\Event\Page\PageEditEvent;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class PageAdminController extends CrudController
{
@@ -50,12 +52,17 @@ class PageAdminController extends CrudController
EntityManager $entityManager,
RepositoryQuery $repositoryQuery,
PageLocator $pageLocator,
+ EventDispatcherInterface $eventDispatcher,
Request $request
): Response {
$entity = $repositoryQuery->filterById($entity)->findOne();
+ $event = new PageEditEvent($entity);
+ $eventDispatcher->dispatch($event, PageEditEvent::FORM_INIT_EVENT);
+
$this->getConfiguration()->setFormOptions('edit', [
- 'pageConfiguration' => $pageLocator->getPage(get_class($entity)),
+ 'page_configuration' => $pageLocator->getPage(get_class($entity)),
+ 'page_builder_options' => $event->getPageBuilderOptions(),
]);
return $this->doEdit($entity, $entityManager, $request);
diff --git a/core/Crud/CrudConfiguration.php b/core/Crud/CrudConfiguration.php
index 3bc0282..3a9935b 100644
--- a/core/Crud/CrudConfiguration.php
+++ b/core/Crud/CrudConfiguration.php
@@ -28,6 +28,7 @@ class CrudConfiguration
protected array $isSortableCollection = [];
protected string $sortableCollectionProperty = 'sortOrder';
protected ?string $defaultLocale = null;
+ protected bool $showActions = true;
protected static $self;
@@ -314,4 +315,16 @@ class CrudConfiguration
{
return $this->sortableCollectionProperty;
}
+
+ public function setShowActions(bool $showActions): self
+ {
+ $this->showActions = $showActions;
+
+ return $this;
+ }
+
+ public function getShowActions(): bool
+ {
+ return $this->showActions;
+ }
}
diff --git a/core/Entity/FileInformation.php b/core/Entity/FileInformation.php
index a93f202..498ffd0 100644
--- a/core/Entity/FileInformation.php
+++ b/core/Entity/FileInformation.php
@@ -36,7 +36,7 @@ class FileInformation implements EntityInterface
public function getAttributes()
{
- return json_decode($this->attributes, true);
+ return (array) json_decode($this->attributes, true);
}
public function setAttributes($attributes): self
diff --git a/core/Entity/Site/Node.php b/core/Entity/Site/Node.php
index 208e201..6e530ef 100644
--- a/core/Entity/Site/Node.php
+++ b/core/Entity/Site/Node.php
@@ -225,12 +225,30 @@ class Node implements EntityInterface
/**
* @return Collection|Node[]
*/
- public function getChildren(): Collection
+ public function getChildren(array $criteria = []): Collection
{
if (null === $this->children) {
$this->children = new ArrayCollection();
}
+ if (!empty($criteria)) {
+ $children = new ArrayCollection();
+
+ foreach ($this->children as $child) {
+ $add = true;
+
+ if (isset($criteria['visible']) && $child->getIsVisible() !== $criteria['visible']) {
+ $add = false;
+ }
+
+ if ($add) {
+ $children->add($child);
+ }
+ }
+
+ return $children;
+ }
+
return $this->children;
}
@@ -256,7 +274,7 @@ class Node implements EntityInterface
return $this;
}
- public function getAllChildren(): ArrayCollection
+ public function getAllChildren(array $criteria = []): ArrayCollection
{
$children = [];
@@ -274,6 +292,14 @@ class Node implements EntityInterface
return $a->getTreeLeft() < $b->getTreeLeft() ? -1 : 1;
});
+ if (!empty($criteria)) {
+ foreach ($children as $key => $child) {
+ if (isset($criteria['visible']) && $child->getIsVisible() !== $criteria['visible']) {
+ unset($children[$key]);
+ }
+ }
+ }
+
return new ArrayCollection($children);
}
@@ -308,6 +334,19 @@ class Node implements EntityInterface
return $string->startsWith('http://') || $string->startsWith('https://');
}
+ public function hasAppUrl(): bool
+ {
+ $string = u($this->getUrl());
+
+ foreach (['tel:', 'fax:', 'mailto:'] as $prefix) {
+ if ($string->startsWith($prefix)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
public function getIsVisible(): ?bool
{
return $this->isVisible;
diff --git a/core/Entity/Site/Page/Page.php b/core/Entity/Site/Page/Page.php
index 58280fd..7d74000 100644
--- a/core/Entity/Site/Page/Page.php
+++ b/core/Entity/Site/Page/Page.php
@@ -140,7 +140,7 @@ class Page implements EntityInterface
return $this;
}
- public function buildForm(FormBuilderInterface $builder)
+ public function buildForm(FormBuilderInterface $builder, array $options)
{
}
diff --git a/core/EventSuscriber/Site/NodeEventSubscriber.php b/core/EventSuscriber/Site/NodeEventSubscriber.php
index 8291623..9b57909 100644
--- a/core/EventSuscriber/Site/NodeEventSubscriber.php
+++ b/core/EventSuscriber/Site/NodeEventSubscriber.php
@@ -133,7 +133,13 @@ class NodeEventSubscriber extends EntityManagerEventSubscriber
$generatedUrl = $generatedUrl.'-'.$number;
}
- if (!u($generatedUrl)->startsWith('https://') && !u($generatedUrl)->startsWith('http://')) {
+ if (
+ !u($generatedUrl)->startsWith('https://')
+ && !u($generatedUrl)->startsWith('http://')
+ && !u($generatedUrl)->startsWith('tel:')
+ && !u($generatedUrl)->startsWith('mailto:')
+ && !u($generatedUrl)->startsWith('fax:')
+ ) {
$generatedUrl = '/'.$generatedUrl;
$generatedUrl = preg_replace('#/{2,}#', '/', $generatedUrl);
}
diff --git a/core/Form/Site/Page/CollectionBlockType.php b/core/Form/Site/Page/CollectionBlockType.php
index 3f46657..d05fe48 100644
--- a/core/Form/Site/Page/CollectionBlockType.php
+++ b/core/Form/Site/Page/CollectionBlockType.php
@@ -16,7 +16,7 @@ class CollectionBlockType extends AbstractType
{
$builder->add(
'value',
- CollectionType::class,
+ $options['collection_type'],
array_merge([
'required' => false,
'label' => false,
@@ -40,6 +40,7 @@ class CollectionBlockType extends AbstractType
{
$resolver->setDefaults([
'data_class' => Block::class,
+ 'collection_type' => CollectionType::class,
'collection_name' => '',
'label_add' => 'Add',
'label_delete' => 'Delete',
diff --git a/core/Form/Site/Page/PageType.php b/core/Form/Site/Page/PageType.php
index b6db1ad..352c740 100644
--- a/core/Form/Site/Page/PageType.php
+++ b/core/Form/Site/Page/PageType.php
@@ -105,7 +105,7 @@ class PageType extends AbstractType
'choices' => call_user_func(function () use ($options) {
$choices = [];
- foreach ($options['pageConfiguration']->getTemplates() as $template) {
+ foreach ($options['page_configuration']->getTemplates() as $template) {
$choices[$template['name']] = $template['file'];
}
@@ -119,14 +119,15 @@ class PageType extends AbstractType
]
);
- $builder->getData()->buildForm($builder);
+ $builder->getData()->buildForm($builder, $options['page_builder_options']);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Page::class,
- 'pageConfiguration' => null,
+ 'page_configuration' => null,
+ 'page_builder_options' => [],
]);
}
}
diff --git a/core/Resources/translations/messages.fr.yaml b/core/Resources/translations/messages.fr.yaml
index f060a1e..6127630 100644
--- a/core/Resources/translations/messages.fr.yaml
+++ b/core/Resources/translations/messages.fr.yaml
@@ -71,6 +71,7 @@
"Page": "Page"
"Administration": "Administration"
"Users": "Utilisateurs"
+"New user": "Nouvel utilisateur⋅trice"
"Back to the list": "Retour à la liste"
"Edit": "Éditer"
"New password": "Nouveau mot de passe"
diff --git a/core/Resources/views/admin/crud/index.html.twig b/core/Resources/views/admin/crud/index.html.twig
index a26035f..2a6546f 100644
--- a/core/Resources/views/admin/crud/index.html.twig
+++ b/core/Resources/views/admin/crud/index.html.twig
@@ -139,9 +139,11 @@
{% endblock %}
{% endfor %}
-
- {{ 'Actions'|trans }}
- |
+ {% if configuration.showActions %}
+
+ {{ 'Actions'|trans }}
+ |
+ {% endif %}
{% endblock %}
@@ -205,34 +207,36 @@
{% endfor %}
-
- {% block list_item_actions_before %}{% endblock %}
+ {% if configuration.showActions %}
+ |
+ {% block list_item_actions_before %}{% endblock %}
- {% if configuration.action(context, 'show', true) %}
-
-
-
- {% endif %}
+ {% if configuration.action(context, 'show', true) %}
+
+
+
+ {% endif %}
- {% if configuration.action(context, 'edit', true) %}
-
-
-
- {% endif %}
+ {% if configuration.action(context, 'edit', true) %}
+
+
+
+ {% endif %}
- {% if configuration.action(context, 'delete', true) %}
-
+ {% if configuration.action(context, 'delete', true) %}
+
-
- {% endif %}
+
+ {% endif %}
- {% block list_item_actions_after %}{% endblock %}
- |
+ {% block list_item_actions_after %}{% endblock %}
+
+ {% endif %}
{% endblock %}
diff --git a/core/Resources/views/form/bootstrap_4_form_theme.html.twig b/core/Resources/views/form/bootstrap_4_form_theme.html.twig
index 14802a5..870f728 100644
--- a/core/Resources/views/form/bootstrap_4_form_theme.html.twig
+++ b/core/Resources/views/form/bootstrap_4_form_theme.html.twig
@@ -44,14 +44,14 @@
{% for child in item %}
{{ form_row(child) }}
{% endfor %}
-
-