Added sorting and position ùmanagement to modules.
This commit is contained in:
@@ -33,6 +33,7 @@ use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Model\Map\ModuleTableMap;
|
||||
use Thelia\Model\ModuleQuery;
|
||||
use Thelia\Module\BaseModule;
|
||||
use Thelia\Core\Event\UpdatePositionEvent;
|
||||
|
||||
/**
|
||||
* Class Module
|
||||
@@ -122,6 +123,16 @@ class Module extends BaseAction implements EventSubscriberInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes position, selecting absolute ou relative change.
|
||||
*
|
||||
* @param CategoryChangePositionEvent $event
|
||||
*/
|
||||
public function updatePosition(UpdatePositionEvent $event)
|
||||
{
|
||||
return $this->genericUpdatePosition(ModuleQuery::create(), $event);
|
||||
}
|
||||
|
||||
protected function cacheClear()
|
||||
{
|
||||
$cacheEvent = new CacheEvent($this->container->getParameter('kernel.cache_dir'));
|
||||
@@ -153,6 +164,7 @@ class Module extends BaseAction implements EventSubscriberInterface
|
||||
{
|
||||
return array(
|
||||
TheliaEvents::MODULE_TOGGLE_ACTIVATION => array('toggleActivation', 128),
|
||||
TheliaEvents::MODULE_UPDATE_POSITION => array('updatePosition', 128),
|
||||
TheliaEvents::MODULE_DELETE => array('delete', 128),
|
||||
TheliaEvents::MODULE_UPDATE => array('update', 128),
|
||||
);
|
||||
|
||||
@@ -954,6 +954,10 @@
|
||||
<default key="_controller">Thelia\Controller\Admin\ModuleController::deleteAction</default>
|
||||
</route>
|
||||
|
||||
<route id="admin.module.delete" path="/admin/module/update-position">
|
||||
<default key="_controller">Thelia\Controller\Admin\ModuleController::updatePositionAction</default>
|
||||
</route>
|
||||
|
||||
<!--
|
||||
Generic module route.
|
||||
Will be use if module route is not define in module own config file.
|
||||
|
||||
@@ -33,6 +33,7 @@ use Thelia\Core\Security\AccessManager;
|
||||
use Thelia\Form\ModuleModificationForm;
|
||||
use Thelia\Model\ModuleQuery;
|
||||
use Thelia\Module\ModuleManagement;
|
||||
use Thelia\Core\Event\UpdatePositionEvent;
|
||||
|
||||
/**
|
||||
* Class ModuleController
|
||||
@@ -45,14 +46,30 @@ class ModuleController extends AbstractCrudController
|
||||
{
|
||||
parent::__construct(
|
||||
'module',
|
||||
null,
|
||||
null,
|
||||
'manual',
|
||||
'module_order',
|
||||
|
||||
AdminResources::MODULE,
|
||||
|
||||
null,
|
||||
TheliaEvents::MODULE_UPDATE,
|
||||
null
|
||||
null,
|
||||
null,
|
||||
TheliaEvents::MODULE_UPDATE_POSITION
|
||||
/*
|
||||
$objectName,
|
||||
|
||||
$defaultListOrder = null,
|
||||
$orderRequestParameterName = null,
|
||||
|
||||
$resourceCode,
|
||||
|
||||
$createEventIdentifier,
|
||||
$updateEventIdentifier,
|
||||
$deleteEventIdentifier,
|
||||
$visibilityToggleEventIdentifier = null,
|
||||
$changePositionEventIdentifier = null
|
||||
*/
|
||||
);
|
||||
}
|
||||
|
||||
@@ -90,6 +107,15 @@ class ModuleController extends AbstractCrudController
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function createUpdatePositionEvent($positionChangeMode, $positionValue)
|
||||
{
|
||||
return new UpdatePositionEvent(
|
||||
$this->getRequest()->get('module_id', null),
|
||||
$positionChangeMode,
|
||||
$positionValue
|
||||
);
|
||||
}
|
||||
|
||||
protected function eventContainsObject($event)
|
||||
{
|
||||
return $event->hasModule();
|
||||
@@ -151,7 +177,7 @@ class ModuleController extends AbstractCrudController
|
||||
// We always return to the feature edition form
|
||||
return $this->render(
|
||||
'modules',
|
||||
array()
|
||||
array('module_order' => $currentOrder)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -185,7 +211,7 @@ class ModuleController extends AbstractCrudController
|
||||
$moduleManagement = new ModuleManagement();
|
||||
$moduleManagement->updateModules();
|
||||
|
||||
return $this->render("modules");
|
||||
return $this->renderList();
|
||||
}
|
||||
|
||||
public function configureAction($module_code)
|
||||
|
||||
@@ -678,9 +678,15 @@ final class TheliaEvents
|
||||
*/
|
||||
const MODULE_TOGGLE_ACTIVATION = 'thelia.module.toggleActivation';
|
||||
|
||||
/**
|
||||
* sent when module position is changed
|
||||
*/
|
||||
const MODULE_UPDATE_POSITION = 'thelia.module.action.updatePosition';
|
||||
|
||||
/**
|
||||
* module
|
||||
*/
|
||||
const MODULE_CREATE = 'thelia.module.create';
|
||||
const MODULE_UPDATE = 'thelia.module.update';
|
||||
const MODULE_DELETE = 'thelia.module.delete';
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ use Thelia\Model\ModuleQuery;
|
||||
|
||||
use Thelia\Module\BaseModule;
|
||||
use Thelia\Type;
|
||||
use Thelia\Type\TypeCollection;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -76,6 +77,13 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface
|
||||
))
|
||||
)
|
||||
),
|
||||
new Argument(
|
||||
'order',
|
||||
new TypeCollection(
|
||||
new Type\EnumListType(array('id', 'id_reverse', 'code', 'code_reverse', 'alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'enabled', 'enabled_reverse'))
|
||||
),
|
||||
'manual'
|
||||
),
|
||||
Argument::createIntListTypeArgument('exclude'),
|
||||
Argument::createBooleanOrBothTypeArgument('active', Type\BooleanOrBothType::ANY)
|
||||
);
|
||||
@@ -126,7 +134,42 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface
|
||||
$search->filterByActivate($active ? 1 : 0, Criteria::EQUAL);
|
||||
}
|
||||
|
||||
$search->orderByPosition();
|
||||
$orders = $this->getOrder();
|
||||
|
||||
foreach ($orders as $order) {
|
||||
switch ($order) {
|
||||
case "id":
|
||||
$search->orderById(Criteria::ASC);
|
||||
break;
|
||||
case "id_reverse":
|
||||
$search->orderById(Criteria::DESC);
|
||||
break;
|
||||
case "alpha":
|
||||
$search->addAscendingOrderByColumn('i18n_TITLE');
|
||||
break;
|
||||
case "alpha_reverse":
|
||||
$search->addDescendingOrderByColumn('i18n_TITLE');
|
||||
break;
|
||||
case "code":
|
||||
$search->orderByCode(Criteria::ASC);
|
||||
break;
|
||||
case "code_reverse":
|
||||
$search->orderByCode(Criteria::DESC);
|
||||
break;
|
||||
case "manual":
|
||||
$search->orderByPosition(Criteria::ASC);
|
||||
break;
|
||||
case "manual_reverse":
|
||||
$search->orderByPosition(Criteria::DESC);
|
||||
break;
|
||||
case "enabled":
|
||||
$search->orderByActivate(Criteria::ASC);
|
||||
break;
|
||||
case "enabled_reverse":
|
||||
$search->orderByActivate(Criteria::DESC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $search;
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@ namespace Thelia\Model;
|
||||
use Propel\Runtime\Connection\ConnectionInterface;
|
||||
use Thelia\Model\Base\Module as BaseModule;
|
||||
use Thelia\Model\Tools\ModelEventDispatcherTrait;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
|
||||
class Module extends BaseModule
|
||||
{
|
||||
use ModelEventDispatcherTrait;
|
||||
|
||||
use \Thelia\Model\Tools\PositionManagementTrait;
|
||||
|
||||
public function postSave(ConnectionInterface $con = null)
|
||||
{
|
||||
ModuleQuery::resetActivated();
|
||||
@@ -56,4 +59,21 @@ class Module extends BaseModule
|
||||
public function getAbsoluteI18nPath() {
|
||||
return THELIA_MODULE_DIR . $this->getI18nPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate next position relative to module type
|
||||
*/
|
||||
protected function addCriteriaToPositionQuery($query) {
|
||||
$query->filterByType($this->getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function preInsert(ConnectionInterface $con = null)
|
||||
{
|
||||
$this->setPosition($this->getNextPosition());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-3">{intl l="Weight lower than ... (kg)"}</th>
|
||||
<th class="col-md-3">{intl l="Weight up to ... (kg)"}</th>
|
||||
<th class="col-md-5">{intl l="Price (€)"}</th>
|
||||
<th class="col-md-1">{intl l="Actions"}</th>
|
||||
</tr>
|
||||
|
||||
@@ -6,9 +6,60 @@
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{intl l="Name"}</th>
|
||||
<th>{intl l="Description"}</th>
|
||||
<th>{intl l="Enable/Disable"}</th>
|
||||
<th>
|
||||
{admin_sortable_header
|
||||
current_order=$module_order
|
||||
order='alpha'
|
||||
reverse_order='alpha_reverse'
|
||||
path={url path='/admin/modules'}
|
||||
request_parameter_name='module_order'
|
||||
label="{intl l='Name'}"
|
||||
}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
{admin_sortable_header
|
||||
current_order=$module_order
|
||||
order='code'
|
||||
reverse_order='code_reverse'
|
||||
path={url path='/admin/modules'}
|
||||
request_parameter_name='module_order'
|
||||
label="{intl l='Code'}"
|
||||
}
|
||||
</th>
|
||||
|
||||
<th>
|
||||
{admin_sortable_header
|
||||
current_order=$module_order
|
||||
order='title'
|
||||
reverse_order='title_reverse'
|
||||
path={url path='/admin/modules'}
|
||||
request_parameter_name='module_order'
|
||||
label="{intl l='Description'}"
|
||||
}
|
||||
</th>
|
||||
|
||||
<th class="text-center">
|
||||
{admin_sortable_header
|
||||
current_order=$module_order
|
||||
order='enabled'
|
||||
reverse_order='enabled_reverse'
|
||||
path={url path='/admin/modules'}
|
||||
request_parameter_name='module_order'
|
||||
label="{intl l='Enable/Disable'}"
|
||||
}
|
||||
</th>
|
||||
|
||||
<th class="text-center">
|
||||
{admin_sortable_header
|
||||
current_order=$module_order
|
||||
order='manual'
|
||||
reverse_order='manual_reverse'
|
||||
path={url path='/admin/modules'}
|
||||
request_parameter_name='module_order'
|
||||
label="{intl l='Position'}"
|
||||
}
|
||||
</th>
|
||||
|
||||
{module_include location='modules_table_header'}
|
||||
|
||||
@@ -17,11 +68,13 @@
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{loop type="module" name="module.{$module_type}" module_type={$module_type|default:1} backend_context=1}
|
||||
{loop type="module" name="module.{$module_type}" module_type={$module_type|default:1} order=$module_order backend_context=1}
|
||||
<tr>
|
||||
<td><a href="#">{$TITLE}</a></td>
|
||||
<td>{$TITLE}</td>
|
||||
<td>{$CODE}</td>
|
||||
<td>{$CHAPO}</td>
|
||||
<td>
|
||||
|
||||
<td class="text-center">
|
||||
<div class="make-switch switch-small module-activation" data-id="{$ID}" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
|
||||
<input type="checkbox" {if $ACTIVE}checked{/if}>
|
||||
</div>
|
||||
@@ -34,6 +87,18 @@
|
||||
</noscript>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
{admin_position_block
|
||||
resource="admin.modules"
|
||||
access="UPDATE"
|
||||
path={url path="admin/module/update-position"}
|
||||
url_parameter="module_id"
|
||||
in_place_edit_class="modulePositionChange"
|
||||
position=$POSITION
|
||||
id=$ID
|
||||
}
|
||||
</td>
|
||||
|
||||
{module_include location='modules_table_row'}
|
||||
|
||||
<td class="text-right">
|
||||
|
||||
@@ -80,6 +80,10 @@
|
||||
<script src="{$asset_url}"></script>
|
||||
{/javascripts}
|
||||
|
||||
{javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'}
|
||||
<script src="{$asset_url}"></script>
|
||||
{/javascripts}
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var url_management = "{url path="/admin/module/toggle-activation/"}";
|
||||
@@ -112,6 +116,28 @@
|
||||
$(".module-delete-action").click(function(){
|
||||
$("#delete_module_id").val($(this).data("id"));
|
||||
});
|
||||
|
||||
{* Inline editing of object position using bootstrap-editable *}
|
||||
|
||||
$('.modulePositionChange').editable({
|
||||
type : 'text',
|
||||
title : '{intl l="Enter new module position"}',
|
||||
mode : 'popup',
|
||||
inputclass : 'input-mini',
|
||||
placement : 'left',
|
||||
success : function(response, newValue) {
|
||||
// The URL template
|
||||
var url = "{url noamp='1' path='/admin/modules/update-position' module_id='__ID__' position='__POS__'}";
|
||||
|
||||
// Perform subtitutions
|
||||
url = url.replace('__ID__', $(this).data('id'))
|
||||
.replace('__POS__', newValue);
|
||||
|
||||
// Reload the page
|
||||
location.href = url;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
Reference in New Issue
Block a user