Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

/etc/build/*
!/etc/build/.gitignore
/etc/export/*
!/etc/export/.gitignore

/tests/TestApplication/.env.local
/tests/TestApplication/.env.*.local
Expand Down
1 change: 1 addition & 0 deletions assets/admin/entrypoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './js/bulk_export';
48 changes: 48 additions & 0 deletions assets/admin/js/bulk_export.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function syliusBulkExport(form) {
const groupName = form.getAttribute('data-bulk-export');
const groupItems = Array.from(document.querySelectorAll(`input[data-check-all-group="${groupName}"]`));

form.addEventListener('submit', (e) => {
e.preventDefault();

const idsInput = form.querySelector('input[name$="[ids]"]');
const ids = [];

groupItems.forEach((item) => {
if (item.checked) {
ids.push(item.value);
}
});
idsInput.setAttribute('value', ids.join(','));

e.target.submit();
});
}

function passDisabledAttributeToDropdownTrigger(trigger) {
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'disabled') {
const button = mutation.target;

if (button.hasAttribute('disabled')) {
button.classList.add('disabled');
} else {
button.classList.remove('disabled');
}
}
}
});

const groupName = trigger.getAttribute('data-check-all');
const dropdownActionButtons = Array.from(document.querySelectorAll(`.dropdown-toggle[data-check-all-action="${groupName}"]`));

dropdownActionButtons.forEach(button => {
observer.observe(button, {'attributes': true});
})
}

(function () {
document.querySelectorAll('[data-check-all]').forEach(passDisabledAttributeToDropdownTrigger);
document.querySelectorAll('[data-bulk-export]').forEach(syliusBulkExport);
}());
3 changes: 3 additions & 0 deletions config/config/sylius_grid.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ sylius_grid:
templates:
action:
export: '@SyliusGridImportExport\admin\import_export\grid\action\export.html.twig'
bulk_action:
export: '@SyliusGridImportExport\admin\import_export\grid\bulk_action\export.html.twig'

grids:
sylius_grid_import_export_admin_process:
driver:
Expand Down
36 changes: 3 additions & 33 deletions config/routes.yaml
Original file line number Diff line number Diff line change
@@ -1,33 +1,3 @@
sylius_import_export.admin.resource.export:
path: /export/{grid}
methods: [POST]
defaults:
_controller: sylius_import_export.controller.export_action
_sylius:
filterable: true

sylius_grid_import_export_admin_process:
resource: |
alias: sylius_grid_import_export.process
section: admin
templates: "@SyliusAdmin\\shared\\crud"
except: ['show', 'create', 'update']
redirect: index
grid: sylius_grid_import_export_admin_process
permission: true
vars:
all:
hook_prefix: 'sylius_b2b.admin.import_export.process'
type: sylius.resource

sylius_grid_import_export_admin_process_show:
path: /import-export/processes/{id}
methods: [ GET ]
defaults:
_controller: sylius_grid_import_export.controller.process::showAction
_sylius:
section: admin
template: '@SyliusAdmin/shared/crud/show.html.twig'
permission: true
vars:
hook_prefix: 'sylius_b2b.admin.import_export.process'
sylius_import_export_admin:
resource: routes/admin.yaml
prefix: '%sylius_admin.path_name%'
33 changes: 33 additions & 0 deletions config/routes/admin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
sylius_import_export.admin.resource.export:
path: /export/{grid}
methods: [POST]
defaults:
_controller: sylius_import_export.controller.export_action
_sylius:
filterable: true

sylius_grid_import_export_admin_process:
resource: |
alias: sylius_grid_import_export.process
section: admin
templates: "@SyliusAdmin\\shared\\crud"
except: ['show', 'create', 'update']
redirect: index
grid: sylius_grid_import_export_admin_process
permission: true
vars:
all:
hook_prefix: 'sylius_b2b.admin.import_export.process'
type: sylius.resource

sylius_grid_import_export_admin_process_show:
path: /import-export/processes/{id}
methods: [ GET ]
defaults:
_controller: sylius_grid_import_export.controller.process::showAction
_sylius:
section: admin
template: '@SyliusAdmin/shared/crud/show.html.twig'
permission: true
vars:
hook_prefix: 'sylius_b2b.admin.import_export.process'
17 changes: 14 additions & 3 deletions config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,18 @@
<tag
name="sylius.twig_component"
key="sylius_import_export:admin:export"
template="@SyliusGridImportExport\admin\import_export\component\export_form.html.twig"
template="@SyliusGridImportExport\admin\import_export\component\main_export_form.html.twig"
/>
</service>

<service id="sylius_import_export.admin.twig.component.bulk_export_resource" class="Sylius\GridImportExport\Twig\Component\ExportResourceFormComponent">
<argument type="service" id="form.factory" />
<argument>%sylius_import_export.export.form_class%</argument>

<tag
name="sylius.twig_component"
key="sylius_import_export:admin:bulk_export"
template="@SyliusGridImportExport\admin\import_export\component\bulk_export_form.html.twig"
/>
</service>

Expand Down Expand Up @@ -110,10 +121,10 @@
<argument type="service" id=".inner" />
</service>

<service id="sylius_import_export.listener.grid.admin.export_action" class="Sylius\Grid\Listener\ExportActionAdminGridListener">
<service id="sylius_import_export.grid.listener.admin.export_action" class="Sylius\GridImportExport\Grid\Listener\ExportActionAdminGridListener">
<argument type="service" id="sylius_import_export.grid.checker.exportable" />

<tag name="kernel.event_listener" event="sylius.grid.common" method="addExportMainAction" />
<tag name="kernel.event_listener" event="sylius.grid.common" method="addExportActions" />
</service>

<service id="sylius_grid_import_export.menu.admin_listener" class="Sylius\GridImportExport\Menu\AdminImportExportMenuListener">
Expand Down
Empty file added etc/export/.gitignore
Empty file.
21 changes: 15 additions & 6 deletions src/Controller/ExportAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ public function __invoke(Request $request, string $grid): Response
$format = $data['format'];
$resourceClass = $data['resourceClass'];

$metadata = $this->metadataRegistry->getByClass($resourceClass);

$resourceIds = $this->resourcesIdsProvider->getResourceIds(
metadata: $metadata,
context: ['request' => $request, 'currentPage' => $data['currentPage'] ?? false],
);
$resourceIds = $this->resolveResourceIds($request, $data);

$this->commandBus->dispatch(new ExportCommand(
resource: $resourceClass,
Expand All @@ -59,4 +54,18 @@ public function __invoke(Request $request, string $grid): Response

return new RedirectResponse($request->headers->get('referer') ?? '/');
}

private function resolveResourceIds(Request $request, array $formData): array
{
if (isset($formData['ids']) && [] !== $formData['ids']) {
return $formData['ids'];
}

$metadata = $this->metadataRegistry->getByClass($formData['resourceClass']);

return $this->resourcesIdsProvider->getResourceIds(
metadata: $metadata,
context: ['request' => $request],
);
}
}
11 changes: 7 additions & 4 deletions src/Form/Type/ExportResourceType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
namespace Sylius\GridImportExport\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
Expand All @@ -34,11 +34,14 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'label' => 'sylius_grid_import_export.grid.form.format',
'choice_loader' => $this->choiceLoader,
])
->add('currentPage', CheckboxType::class, [
'label' => 'sylius_grid_import_export.grid.form.current_page',
])
->add('ids', HiddenType::class)
->add('resourceClass', HiddenType::class)
;

$builder->get('ids')->addModelTransformer(new CallbackTransformer(
static fn (?array $ids): string => $ids ? implode(',', $ids) : '',
static fn (?string $ids): array => $ids ? array_filter(array_map('trim', explode(',', $ids))) : [],
));
}

public function getBlockPrefix(): string
Expand Down
22 changes: 16 additions & 6 deletions src/Grid/Listener/ExportActionAdminGridListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,24 @@

namespace Sylius\GridImportExport\Grid\Listener;

use Sylius\Bundle\GridBundle\Builder\ActionGroup\ActionGroupInterface;
use Sylius\Bundle\GridBundle\Doctrine\ORM\Driver as ORMDriver;
use Sylius\Component\Grid\Definition\Action;
use Sylius\Component\Grid\Definition\ActionGroup;
use Sylius\Component\Grid\Definition\Grid;
use Sylius\Component\Grid\Event\GridDefinitionConverterEvent;
use Sylius\GridImportExport\Grid\Checker\ExportableCheckerInterface;

final readonly class ExportActionAdminGridListener
{
private const EXPORT_ACTION_NAME = 'export';

public function __construct(
private ExportableCheckerInterface $exportableChecker,
) {
}

public function addExportMainAction(GridDefinitionConverterEvent $event): void
public function addExportActions(GridDefinitionConverterEvent $event): void
{
$grid = $event->getGrid();
if (ORMDriver::NAME !== $grid->getDriver()) {
Expand All @@ -37,16 +41,22 @@ public function addExportMainAction(GridDefinitionConverterEvent $event): void
return;
}

if (!$grid->hasActionGroup('main')) {
$grid->addActionGroup(ActionGroup::named('main'));
$this->addInActionGroup($grid, ActionGroupInterface::MAIN_GROUP);
$this->addInActionGroup($grid, ActionGroupInterface::BULK_GROUP);
}

private function addInActionGroup(Grid $grid, string $groupName): void
{
if (!$grid->hasActionGroup($groupName)) {
$grid->addActionGroup(ActionGroup::named($groupName));
}

$actionGroup = $grid->getActionGroup('main');
if ($actionGroup->hasAction('export')) {
$actionGroup = $grid->getActionGroup($groupName);
if ($actionGroup->hasAction(self::EXPORT_ACTION_NAME)) {
return;
}

$action = Action::fromNameAndType('export', 'export');
$action = Action::fromNameAndType(self::EXPORT_ACTION_NAME, self::EXPORT_ACTION_NAME);

$actionGroup->addAction($action);
}
Expand Down
12 changes: 2 additions & 10 deletions src/Provider/RequestBasedResourcesIdsProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public function getResourceIds(MetadataInterface $metadata, array $context = [])
throw new ProviderException('Request is missing from the context.');
}

return $this->doGetResourceIds($metadata, $request, $context['currentPage'] ?? false);
return $this->doGetResourceIds($metadata, $request);
}

private function doGetResourceIds(MetadataInterface $metadata, Request $request, bool $currentPage): array
private function doGetResourceIds(MetadataInterface $metadata, Request $request): array
{
$resourceClass = $metadata->getClass('model');
/** @var RepositoryInterface $repository */
Expand All @@ -64,14 +64,6 @@ private function doGetResourceIds(MetadataInterface $metadata, Request $request,
}

$ids = [];
if ($currentPage) {
foreach ($paginator->getCurrentPageResults() as $item) {
$ids[] = (string) $item->getId();
}

return $ids;
}

foreach ($paginator->autoPagingIterator() as $item) {
$ids[] = (string) $item->getId();
}
Expand Down
32 changes: 32 additions & 0 deletions templates/admin/import_export/component/bulk_export_form.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{# Rendered with \Sylius\GridImportExport\Twig\Component\ExportResourceFormComponent #}

{% import '@SyliusAdmin/shared/helper/button.html.twig' as button %}

{% form_theme form '@SyliusAdmin/shared/form_theme.html.twig' %}

{% set export_parameters = {
'grid': grid,
'criteria': app.request.query.all()['criteria']|default({}),
} %}

<div class="dropdown">
<button class="btn btn-ghost-primary dropdown-toggle" disabled type="button" data-bs-toggle="dropdown" aria-expanded="false" data-check-all-action="index">
{{ 'sylius_grid_import_export.ui.export'|trans }}
</button>
<div class="dropdown-menu p-4">
{{ form_start(form, {'action': path('sylius_import_export.admin.resource.export', export_parameters), 'attr': {'novalidate': 'novalidate', 'data-bulk-export': 'index'}}) }}

<div class="mb-3">
{{ form_row(form.format) }}
</div>

<div class="d-flex justify-content-end">
{{ button.primary({'type': 'submit', 'text': 'sylius_grid_import_export.ui.export'|trans}) }}
</div>

{{ form_widget(form.resourceClass) }}
{{ form_widget(form.ids) }}
{{ form_row(form._token) }}
{{ form_end(form, {'render_rest': false}) }}
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

<div class="mb-3">
{{ form_row(form.format) }}
{{ form_row(form.currentPage) }}
</div>

<div class="d-flex justify-content-end">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ component('sylius_import_export:admin:bulk_export', {'grid': grid.definition.code, 'resourceClass': grid.definition.driverConfiguration['class']}) }}
3 changes: 3 additions & 0 deletions tests/TestApplication/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ imports:
- { resource: "@SyliusGridImportExportBundle/config/config.yaml" }
- { resource: "services_test.php" }

parameters:
sylius_grid_import_export.export_files_directory: '%kernel.project_dir%/../../../etc/export'

twig:
paths:
'%kernel.project_dir%/../../../tests/TestApplication/templates': ~
1 change: 0 additions & 1 deletion translations/messages.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ sylius_grid_import_export:
form:
export: Export
format: Format
current_page: Current page
ui:
export: "Export"
import_export: "Import / export"
Expand Down