Added sorting and position ùmanagement to modules.

This commit is contained in:
Franck Allimant
2013-12-06 18:59:46 +01:00
parent e96088080d
commit 8c864021f5
9 changed files with 215 additions and 13 deletions

View File

@@ -33,6 +33,7 @@ use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Map\ModuleTableMap; use Thelia\Model\Map\ModuleTableMap;
use Thelia\Model\ModuleQuery; use Thelia\Model\ModuleQuery;
use Thelia\Module\BaseModule; use Thelia\Module\BaseModule;
use Thelia\Core\Event\UpdatePositionEvent;
/** /**
* Class Module * 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() protected function cacheClear()
{ {
$cacheEvent = new CacheEvent($this->container->getParameter('kernel.cache_dir')); $cacheEvent = new CacheEvent($this->container->getParameter('kernel.cache_dir'));
@@ -153,6 +164,7 @@ class Module extends BaseAction implements EventSubscriberInterface
{ {
return array( return array(
TheliaEvents::MODULE_TOGGLE_ACTIVATION => array('toggleActivation', 128), TheliaEvents::MODULE_TOGGLE_ACTIVATION => array('toggleActivation', 128),
TheliaEvents::MODULE_UPDATE_POSITION => array('updatePosition', 128),
TheliaEvents::MODULE_DELETE => array('delete', 128), TheliaEvents::MODULE_DELETE => array('delete', 128),
TheliaEvents::MODULE_UPDATE => array('update', 128), TheliaEvents::MODULE_UPDATE => array('update', 128),
); );

View File

@@ -954,6 +954,10 @@
<default key="_controller">Thelia\Controller\Admin\ModuleController::deleteAction</default> <default key="_controller">Thelia\Controller\Admin\ModuleController::deleteAction</default>
</route> </route>
<route id="admin.module.delete" path="/admin/module/update-position">
<default key="_controller">Thelia\Controller\Admin\ModuleController::updatePositionAction</default>
</route>
<!-- <!--
Generic module route. Generic module route.
Will be use if module route is not define in module own config file. Will be use if module route is not define in module own config file.

View File

@@ -33,6 +33,7 @@ use Thelia\Core\Security\AccessManager;
use Thelia\Form\ModuleModificationForm; use Thelia\Form\ModuleModificationForm;
use Thelia\Model\ModuleQuery; use Thelia\Model\ModuleQuery;
use Thelia\Module\ModuleManagement; use Thelia\Module\ModuleManagement;
use Thelia\Core\Event\UpdatePositionEvent;
/** /**
* Class ModuleController * Class ModuleController
@@ -45,14 +46,30 @@ class ModuleController extends AbstractCrudController
{ {
parent::__construct( parent::__construct(
'module', 'module',
null, 'manual',
null, 'module_order',
AdminResources::MODULE, AdminResources::MODULE,
null, null,
TheliaEvents::MODULE_UPDATE, 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; return null;
} }
protected function createUpdatePositionEvent($positionChangeMode, $positionValue)
{
return new UpdatePositionEvent(
$this->getRequest()->get('module_id', null),
$positionChangeMode,
$positionValue
);
}
protected function eventContainsObject($event) protected function eventContainsObject($event)
{ {
return $event->hasModule(); return $event->hasModule();
@@ -151,7 +177,7 @@ class ModuleController extends AbstractCrudController
// We always return to the feature edition form // We always return to the feature edition form
return $this->render( return $this->render(
'modules', 'modules',
array() array('module_order' => $currentOrder)
); );
} }
@@ -185,7 +211,7 @@ class ModuleController extends AbstractCrudController
$moduleManagement = new ModuleManagement(); $moduleManagement = new ModuleManagement();
$moduleManagement->updateModules(); $moduleManagement->updateModules();
return $this->render("modules"); return $this->renderList();
} }
public function configureAction($module_code) public function configureAction($module_code)

View File

@@ -678,9 +678,15 @@ final class TheliaEvents
*/ */
const MODULE_TOGGLE_ACTIVATION = 'thelia.module.toggleActivation'; const MODULE_TOGGLE_ACTIVATION = 'thelia.module.toggleActivation';
/**
* sent when module position is changed
*/
const MODULE_UPDATE_POSITION = 'thelia.module.action.updatePosition';
/** /**
* module * module
*/ */
const MODULE_CREATE = 'thelia.module.create';
const MODULE_UPDATE = 'thelia.module.update'; const MODULE_UPDATE = 'thelia.module.update';
const MODULE_DELETE = 'thelia.module.delete'; const MODULE_DELETE = 'thelia.module.delete';

View File

@@ -38,6 +38,7 @@ use Thelia\Model\ModuleQuery;
use Thelia\Module\BaseModule; use Thelia\Module\BaseModule;
use Thelia\Type; 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::createIntListTypeArgument('exclude'),
Argument::createBooleanOrBothTypeArgument('active', Type\BooleanOrBothType::ANY) Argument::createBooleanOrBothTypeArgument('active', Type\BooleanOrBothType::ANY)
); );
@@ -126,7 +134,42 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface
$search->filterByActivate($active ? 1 : 0, Criteria::EQUAL); $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; return $search;

View File

@@ -5,11 +5,14 @@ namespace Thelia\Model;
use Propel\Runtime\Connection\ConnectionInterface; use Propel\Runtime\Connection\ConnectionInterface;
use Thelia\Model\Base\Module as BaseModule; use Thelia\Model\Base\Module as BaseModule;
use Thelia\Model\Tools\ModelEventDispatcherTrait; use Thelia\Model\Tools\ModelEventDispatcherTrait;
use Thelia\Core\Event\TheliaEvents;
class Module extends BaseModule class Module extends BaseModule
{ {
use ModelEventDispatcherTrait; use ModelEventDispatcherTrait;
use \Thelia\Model\Tools\PositionManagementTrait;
public function postSave(ConnectionInterface $con = null) public function postSave(ConnectionInterface $con = null)
{ {
ModuleQuery::resetActivated(); ModuleQuery::resetActivated();
@@ -56,4 +59,21 @@ class Module extends BaseModule
public function getAbsoluteI18nPath() { public function getAbsoluteI18nPath() {
return THELIA_MODULE_DIR . $this->getI18nPath(); 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;
}
} }

View File

@@ -25,7 +25,7 @@
</caption> </caption>
<thead> <thead>
<tr> <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-5">{intl l="Price (€)"}</th>
<th class="col-md-1">{intl l="Actions"}</th> <th class="col-md-1">{intl l="Actions"}</th>
</tr> </tr>

View File

@@ -6,9 +6,60 @@
</caption> </caption>
<thead> <thead>
<tr> <tr>
<th>{intl l="Name"}</th> <th>
<th>{intl l="Description"}</th> {admin_sortable_header
<th>{intl l="Enable/Disable"}</th> 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'} {module_include location='modules_table_header'}
@@ -17,11 +68,13 @@
</thead> </thead>
<tbody> <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> <tr>
<td><a href="#">{$TITLE}</a></td> <td>{$TITLE}</td>
<td>{$CODE}</td>
<td>{$CHAPO}</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>"> <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}> <input type="checkbox" {if $ACTIVE}checked{/if}>
</div> </div>
@@ -34,6 +87,18 @@
</noscript> </noscript>
</td> </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'} {module_include location='modules_table_row'}
<td class="text-right"> <td class="text-right">

View File

@@ -80,6 +80,10 @@
<script src="{$asset_url}"></script> <script src="{$asset_url}"></script>
{/javascripts} {/javascripts}
{javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'}
<script src="{$asset_url}"></script>
{/javascripts}
<script> <script>
$(document).ready(function() { $(document).ready(function() {
var url_management = "{url path="/admin/module/toggle-activation/"}"; var url_management = "{url path="/admin/module/toggle-activation/"}";
@@ -112,6 +116,28 @@
$(".module-delete-action").click(function(){ $(".module-delete-action").click(function(){
$("#delete_module_id").val($(this).data("id")); $("#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> </script>
{/block} {/block}