feat(main): Draggable blocks

This commit is contained in:
2026-08-12 15:39:07 +02:00
parent 1493081602
commit d0da05845a
8 changed files with 74 additions and 6 deletions
+10
View File
@@ -68,3 +68,13 @@ services:
- '@websmid.customhtml.grid.data.factory.customhtmlblock_data_factory'
- '@prestashop.core.grid.filter.form_factory'
- '@prestashop.core.hook.dispatcher'
websmid.customhtml.grid.position.customhtmlblock_position_definition:
public: true
class: 'PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinition'
arguments:
- 'ws_customhtml'
- 'id_ws_customhtml'
- 'ordering'
- 'id_ws_customhtml_group'
- 0
+6
View File
@@ -71,3 +71,9 @@ customhtmlblock_delete:
methods: [DELETE, GET, POST]
defaults:
_controller: 'Websmid\CustomHtml\Controller\CustomHtmlBlockController::deleteAction'
customhtmlblock_update_position:
path: ws_customhtml/block/{idGroup}/update-position
methods: [POST]
defaults:
_controller: 'Websmid\CustomHtml\Controller\CustomHtmlBlockController::updatePositionAction'
@@ -3,6 +3,9 @@
namespace Websmid\CustomHtml\Controller;
use Exception;
use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionUpdateException;
use PrestaShop\PrestaShop\Core\Grid\Position\GridPositionUpdaterInterface;
use PrestaShop\PrestaShop\Core\Grid\Position\PositionUpdateFactoryInterface;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use PrestaShopBundle\Security\Voter\PageVoter;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -115,6 +118,28 @@ class CustomHtmlBlockController extends FrameworkBundleAdminController
return $this->redirectToRoute('customhtmlblock_index');
}
public function updatePositionAction(int $idGroup, Request $request): RedirectResponse
{
$positionDefinition = $this->get('websmid.customhtml.grid.position.customhtmlblock_position_definition');
try {
$positionUpdateFactory = $this->get(PositionUpdateFactoryInterface::class);
$positionUpdate = $positionUpdateFactory->buildPositionUpdate([
'positions' => $request->request->all('positions'),
'parentId' => $idGroup,
], $positionDefinition);
$updater = $this->get(GridPositionUpdaterInterface::class);
$updater->update($positionUpdate);
$this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success'));
} catch (PositionUpdateException $e) {
$this->addFlash('error', $this->getErrorMessageForException($e, []));
}
return $this->redirectToRoute('customhtmlblock_index', ['idGroup' => $idGroup]);
}
private function getToolbarButtons(?string $securitySubject): array
{
$toolbarButtons = [];
@@ -5,20 +5,23 @@ namespace Websmid\CustomHtml\Form\DataHandler;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface;
use Websmid\CustomHtml\Model\CustomHtmlBlock;
use Websmid\CustomHtml\Model\CustomHtmlFaq;
use Db;
use Validate;
final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface
{
public function create(array $formData)
{
$idGroup = (int) $formData['id_ws_customhtml_group'];
$block = new CustomHtmlBlock();
$block->id_ws_customhtml_group = (int) $formData['id_ws_customhtml_group'];
$block->id_ws_customhtml_group = $idGroup;
$block->title = (string) $formData['title'];
$block->type = (string) $formData['type'];
$block->show_title = (int) $formData['show_title'];
$block->content = (string) $formData['content'];
$block->active = (int) $formData['active'];
$block->ordering = 0;
$block->ordering = $this->getNextOrdering($idGroup);
if (!$block->add()) {
return false;
@@ -53,6 +56,16 @@ final class CustomHtmlBlockDataHandler implements FormDataHandlerInterface
return true;
}
private function getNextOrdering(int $idGroup): int
{
$maxOrdering = Db::getInstance()->getValue(
'SELECT MAX(`ordering`) FROM `' . _DB_PREFIX_ . 'ws_customhtml`
WHERE `id_ws_customhtml_group` = ' . $idGroup
);
return $maxOrdering === false || $maxOrdering === null ? 0 : ((int) $maxOrdering + 1);
}
private function saveFaqs(int $idBlock, array $faqs): void
{
CustomHtmlFaq::deleteByBlockId($idBlock);
@@ -8,6 +8,7 @@ use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction;
use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction;
use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PositionColumn;
use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn;
use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AbstractGridDefinitionFactory;
use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\DeleteActionTrait;
@@ -84,9 +85,18 @@ final class CustomHtmlBlockGridDefinitionFactory extends AbstractGridDefinitionF
->setOptions(['field' => 'active'])
)
->add(
(new DataColumn('ordering'))
(new PositionColumn('position'))
->setName($this->trans('Position', [], 'Modules.Wscustomhtml.Admin'))
->setOptions(['field' => 'ordering'])
->setOptions([
'id_field' => 'id_ws_customhtml',
'position_field' => 'ordering',
'update_method' => 'POST',
'update_route' => 'customhtmlblock_update_position',
'record_route_params' => [
'id_ws_customhtml_group' => 'idGroup',
],
'required_filter' => 'id_ws_customhtml_group',
])
)
->add(
(new DataColumn('date_add'))
+1 -1
View File
@@ -14,7 +14,7 @@ final class CustomHtmlBlockFilters extends Filters
return [
'limit' => 10,
'offset' => 0,
'orderBy' => 'wchb.id_ws_customhtml',
'orderBy' => 'position',
'sortOrder' => 'asc',
'filters' => [],
];
@@ -43,6 +43,7 @@ final class CustomHtmlBlockQueryBuilder extends AbstractDoctrineQueryBuilder
$qb->select(
'wchb.`id_ws_customhtml`',
'wchb.`id_ws_customhtml_group`',
'wchb.`title`',
'wchg.`title` AS group_title',
'wchb.`type`',
@@ -53,8 +54,10 @@ final class CustomHtmlBlockQueryBuilder extends AbstractDoctrineQueryBuilder
$this->applyFilters($qb, $searchCriteria);
$orderBy = $searchCriteria->getOrderBy() === 'position' ? 'wchb.ordering' : $searchCriteria->getOrderBy();
$qb
->orderBy($searchCriteria->getOrderBy(), $searchCriteria->getOrderWay())
->orderBy($orderBy, $searchCriteria->getOrderWay())
->setFirstResult($searchCriteria->getOffset() ?? 0)
->setMaxResults($searchCriteria->getLimit());
@@ -20,6 +20,7 @@
customhtmlblockGrid.addExtension(new window.prestashop.component.GridExtensions.FiltersResetExtension());
customhtmlblockGrid.addExtension(new window.prestashop.component.GridExtensions.ColumnTogglingExtension());
customhtmlblockGrid.addExtension(new window.prestashop.component.GridExtensions.SubmitRowActionExtension());
customhtmlblockGrid.addExtension(new window.prestashop.component.GridExtensions.PositionExtension());
});
</script>
{% endblock %}