Improved back office config with tabs
This commit is contained in:
Binary file not shown.
@@ -5,10 +5,13 @@ accounts.
|
||||
|
||||
## What it does
|
||||
|
||||
- Back office: a **Customer Specialties** admin screen (under Customers) lets you maintain the
|
||||
list of selectable specialty values (title per language, position, active/inactive). Values
|
||||
are never hard-deleted from the UI, only deactivated, since they may already be linked to
|
||||
customers.
|
||||
- Back office: clicking **Configure** on the module (Modules list) opens a "Settings" panel with
|
||||
the front-office display toggle, and a small tab-style nav that also links to a **Specialties**
|
||||
grid for maintaining the list of selectable specialty values (title per language,
|
||||
active/inactive, move up/down). Values are never hard-deleted from the UI, only deactivated,
|
||||
since they may already be linked to customers. The Specialties admin page is intentionally
|
||||
**not** registered in the back-office sidebar menu (`id_parent => -1` on its tab, per this
|
||||
module's own conventions doc, section 18) — Configure is the only entry point, by design.
|
||||
- Back office: the native "Add/Edit customer" page gets a required "Specialty" dropdown, and the
|
||||
native Customers grid gets a sortable/filterable "Specialty" column and a read-only specialty
|
||||
block on the customer view page.
|
||||
@@ -51,15 +54,17 @@ not something the module can safely do on your behalf without overriding core ma
|
||||
|
||||
- No drag-and-drop reordering of specialty values. The grid has "Move up" / "Move down" row
|
||||
actions instead (`customerspecialty_move_up` / `_move_down` routes swapping `position` with the
|
||||
adjacent row). This avoids depending on PrestaShop's core Grid position/drag-reorder plumbing,
|
||||
whose exact API wasn't verified live against a running 1.7 and 9.0 instance.
|
||||
adjacent row). This avoids depending on PrestaShop's core Grid position/drag-reorder plumbing.
|
||||
- The active/inactive toggle uses a `ToggleColumn` + `customerspecialty_toggle_active` route. If
|
||||
that route ever misbehaves on a given PrestaShop version, active/inactive can always be changed
|
||||
via the Edit form as a fallback — it isn't the only way to flip the flag.
|
||||
- Grid `getFilters()`/`getColumns()` option keys (`ToggleColumn`, `SearchAndResetType`) follow the
|
||||
standard, long-stable PrestaShop Grid API from memory; they were not verified against a live
|
||||
PrestaShop 1.7 or 9.0 install (per request, devdocs research was skipped for this build). Smoke
|
||||
test the "Customer Specialties" admin grid after install before relying on it in production.
|
||||
|
||||
Confirmed working live on PrestaShop 9: create, edit, and active/inactive toggle on the
|
||||
Specialties grid. Three real bugs were found and fixed this way (not by static guessing) during
|
||||
initial rollout: a wrong `FormDataProviderInterface` namespace, a missing `LinkRowAction`
|
||||
`route_param_field` option, and `FrameworkBundleAdminController::trans()` taking `(key, domain,
|
||||
params)` instead of `Module::trans()`'s `(key, params, domain)`. "Move up"/"Move down" reordering
|
||||
has not been explicitly click-tested yet — verify before relying on it.
|
||||
|
||||
## Biggest assumption to verify
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class Config
|
||||
const TABS = [
|
||||
[
|
||||
'class_name' => 'AdminCustomerSpecialtyOverview',
|
||||
'parent_class_name' => 'AdminParentCustomer',
|
||||
'id_parent' => -1,
|
||||
'name' => [
|
||||
'en' => 'Customer Specialties',
|
||||
'nl' => 'Klantspecialisaties',
|
||||
|
||||
@@ -24,9 +24,17 @@ class CustomerSpecialtyController extends FrameworkBundleAdminController
|
||||
return $this->render('@Modules/ws_customerspecialty/views/templates/admin/grid/customerspecialty.html.twig', [
|
||||
'customerSpecialtyGrid' => $this->presentGrid($grid),
|
||||
'layoutHeaderToolbarBtn' => $this->getToolbarButtons($request->get('_legacy_controller')),
|
||||
'settingsUrl' => $this->getSettingsUrl(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function getSettingsUrl(): string
|
||||
{
|
||||
$legacyContext = $this->get('prestashop.adapter.legacy.context')->getContext();
|
||||
|
||||
return $legacyContext->link->getAdminLink('AdminModules') . '&configure=ws_customerspecialty';
|
||||
}
|
||||
|
||||
public function searchAction(Request $request): RedirectResponse
|
||||
{
|
||||
return $this->get('prestashop.bundle.grid.response_builder')->buildSearchResponse(
|
||||
@@ -49,7 +57,7 @@ class CustomerSpecialtyController extends FrameworkBundleAdminController
|
||||
$handlerResult = $formHandler->handle($form);
|
||||
|
||||
if (null !== $handlerResult->getIdentifiableObjectId()) {
|
||||
$this->addFlash('success', $this->trans('Successful creation', [], 'Admin.Notifications.Success'));
|
||||
$this->addFlash('success', $this->trans('Successful creation', 'Admin.Notifications.Success'));
|
||||
|
||||
return $this->redirectToRoute('customerspecialty_index');
|
||||
}
|
||||
@@ -74,7 +82,7 @@ class CustomerSpecialtyController extends FrameworkBundleAdminController
|
||||
$handlerResult = $formHandler->handleFor($idCustomerSpecialty, $form);
|
||||
|
||||
if ($handlerResult->isSubmitted() && $handlerResult->isValid()) {
|
||||
$this->addFlash('success', $this->trans('Successful update', [], 'Admin.Notifications.Success'));
|
||||
$this->addFlash('success', $this->trans('Successful update', 'Admin.Notifications.Success'));
|
||||
|
||||
return $this->redirectToRoute('customerspecialty_index');
|
||||
}
|
||||
@@ -91,7 +99,7 @@ class CustomerSpecialtyController extends FrameworkBundleAdminController
|
||||
{
|
||||
try {
|
||||
$this->getCommandBus()->handle(new ToggleCustomerSpecialtyActiveCommand($idCustomerSpecialty));
|
||||
$this->addFlash('success', $this->trans('Successful update', [], 'Admin.Notifications.Success'));
|
||||
$this->addFlash('success', $this->trans('Successful update', 'Admin.Notifications.Success'));
|
||||
} catch (Exception $e) {
|
||||
$this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages()));
|
||||
}
|
||||
@@ -130,7 +138,7 @@ class CustomerSpecialtyController extends FrameworkBundleAdminController
|
||||
|
||||
$toolbarButtons['customerspecialty_create'] = [
|
||||
'href' => $this->generateUrl('customerspecialty_create'),
|
||||
'desc' => $this->trans('New specialty', [], 'Admin.Actions'),
|
||||
'desc' => $this->trans('New specialty', 'Admin.Actions'),
|
||||
'icon' => 'add_circle_outline',
|
||||
'class' => 'btn-primary',
|
||||
'floating_class' => '',
|
||||
|
||||
@@ -32,6 +32,7 @@ trait AdminHooks
|
||||
'front_enabled' => (bool) Configuration::get(Config::FRONT_ENABLED_CONFIG_KEY),
|
||||
'form_action' => $this->context->link->getAdminLink('AdminModules') . '&configure=' . $this->name,
|
||||
'confirmation' => $confirmation,
|
||||
'specialties_url' => $this->get('router')->generate('customerspecialty_index'),
|
||||
]);
|
||||
|
||||
return $this->fetch('module:ws_customerspecialty/views/templates/admin/configuration.tpl');
|
||||
|
||||
@@ -95,30 +95,35 @@ trait Install
|
||||
$languages = Language::getLanguages(false);
|
||||
|
||||
foreach ($moduleTabs as $moduleTab) {
|
||||
if (Tab::getIdFromClassName($moduleTab['class_name'])) {
|
||||
continue;
|
||||
}
|
||||
$idTab = (int) Tab::getIdFromClassName($moduleTab['class_name']);
|
||||
$tab = $idTab ? new Tab($idTab) : new Tab();
|
||||
|
||||
$tab = new Tab();
|
||||
$tab->class_name = $moduleTab['class_name'];
|
||||
$tab->module = $moduleTab['module'];
|
||||
$tab->active = (int) $moduleTab['active'];
|
||||
$tab->route_name = $moduleTab['route_name'];
|
||||
$tab->icon = $moduleTab['icon'];
|
||||
$tab->id_parent = (int) Tab::getIdFromClassName($moduleTab['parent_class_name']);
|
||||
$tab->id_parent = $this->resolveTabParentId($moduleTab);
|
||||
|
||||
foreach ($languages as $language) {
|
||||
$tab->name[(int) $language['id_lang']] = $moduleTab['name'][$language['iso_code']]
|
||||
?? $moduleTab['name']['en'];
|
||||
}
|
||||
|
||||
$tab->add();
|
||||
|
||||
if (!$tab->id) {
|
||||
if (!$tab->save()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function resolveTabParentId(array $moduleTab): int
|
||||
{
|
||||
if (array_key_exists('id_parent', $moduleTab)) {
|
||||
return (int) $moduleTab['id_parent'];
|
||||
}
|
||||
|
||||
return (int) Tab::getIdFromClassName($moduleTab['parent_class_name']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
{$confirmation nofilter}
|
||||
{/if}
|
||||
|
||||
<ul class="nav nav-tabs" style="margin-bottom: 20px;">
|
||||
<li class="active"><a href="#"><i class="icon-cogs"></i> {l s='Settings' d='Modules.Wscustomerspecialty.Admin'}</a></li>
|
||||
<li><a href="{$specialties_url|escape:'htmlall':'UTF-8'}"><i class="icon-list"></i> {l s='Specialties' d='Modules.Wscustomerspecialty.Admin'}</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<i class="icon-user"></i>
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
{% extends '@PrestaShop/Admin/layout.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<ul class="nav nav-tabs" style="margin-bottom: 20px;">
|
||||
<li><a href="{{ settingsUrl }}"><i class="material-icons">settings</i> {{ 'Settings'|trans({}, 'Modules.Wscustomerspecialty.Admin') }}</a></li>
|
||||
<li class="active"><a href="#"><i class="material-icons">list</i> {{ 'Specialties'|trans({}, 'Modules.Wscustomerspecialty.Admin') }}</a></li>
|
||||
</ul>
|
||||
|
||||
{% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': customerSpecialtyGrid} %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user