mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
Add a basic add an attribute mechanism
This commit is contained in:
parent
4a8817b829
commit
13d24369cb
15 changed files with 196 additions and 1 deletions
|
|
@ -130,6 +130,7 @@
|
||||||
"symfony/templating": "^6.4.0",
|
"symfony/templating": "^6.4.0",
|
||||||
"symfony/translation": "^6.4.0",
|
"symfony/translation": "^6.4.0",
|
||||||
"symfony/translation-contracts": "^2.5.2",
|
"symfony/translation-contracts": "^2.5.2",
|
||||||
|
"symfony/ux-autocomplete": "2.x-dev",
|
||||||
"symfony/ux-live-component": "^2.12",
|
"symfony/ux-live-component": "^2.12",
|
||||||
"symfony/ux-twig-component": "^2.11.2",
|
"symfony/ux-twig-component": "^2.11.2",
|
||||||
"symfony/twig-bundle": "^6.4.0",
|
"symfony/twig-bundle": "^6.4.0",
|
||||||
|
|
|
||||||
|
|
@ -63,4 +63,5 @@ return [
|
||||||
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
||||||
Symfony\UX\LiveComponent\LiveComponentBundle::class => ['all' => true],
|
Symfony\UX\LiveComponent\LiveComponentBundle::class => ['all' => true],
|
||||||
Sylius\TwigHooks\TwigHooksBundle::class => ['all' => true],
|
Sylius\TwigHooks\TwigHooksBundle::class => ['all' => true],
|
||||||
|
Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
3
config/routes/ux_autocomplete.yaml
Normal file
3
config/routes/ux_autocomplete.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
ux_autocomplete:
|
||||||
|
resource: '@AutocompleteBundle/config/routes.php'
|
||||||
|
prefix: '/autocomplete'
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
"@hotwired/stimulus": "^3.0.0",
|
"@hotwired/stimulus": "^3.0.0",
|
||||||
"@semantic-ui-react/css-patch": "^1.1.2",
|
"@semantic-ui-react/css-patch": "^1.1.2",
|
||||||
"@symfony/stimulus-bridge": "^3.2.0",
|
"@symfony/stimulus-bridge": "^3.2.0",
|
||||||
|
"@symfony/ux-autocomplete": "file:vendor/symfony/ux-autocomplete/assets",
|
||||||
"@symfony/webpack-encore": "^3.1.0",
|
"@symfony/webpack-encore": "^3.1.0",
|
||||||
"eslint": "^8.23.0",
|
"eslint": "^8.23.0",
|
||||||
"eslint-config-airbnb-base": "^15.0.0",
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
|
|
@ -39,6 +40,7 @@
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"sass": "^1.54.8",
|
"sass": "^1.54.8",
|
||||||
"sass-loader": "^13.0.0",
|
"sass-loader": "^13.0.0",
|
||||||
|
"tom-select": "^2.2.2",
|
||||||
"yargs": "^17.5.1"
|
"yargs": "^17.5.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\AdminBundle\Autocompleter;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
use Symfony\UX\Autocomplete\EntityAutocompleterInterface;
|
||||||
|
|
||||||
|
final readonly class ProductAttributeAutocompleter implements EntityAutocompleterInterface
|
||||||
|
{
|
||||||
|
public function __construct (
|
||||||
|
private string $productAttributeClass,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEntityClass(): string
|
||||||
|
{
|
||||||
|
return $this->productAttributeClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createFilteredQueryBuilder(EntityRepository $repository, string $query): QueryBuilder
|
||||||
|
{
|
||||||
|
return $repository->createQueryBuilder('o')
|
||||||
|
->andWhere('o.code LIKE :query')
|
||||||
|
->setParameter('query', '%' . $query . '%')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabel(object $entity): string
|
||||||
|
{
|
||||||
|
return $entity->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue(object $entity): mixed
|
||||||
|
{
|
||||||
|
return $entity->getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isGranted(Security $security): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import LiveController from '@symfony/ux-live-component';
|
||||||
import '@symfony/ux-live-component/styles/live.css';
|
import '@symfony/ux-live-component/styles/live.css';
|
||||||
import SlugController from "./controllers/SlugController";
|
import SlugController from "./controllers/SlugController";
|
||||||
import TaxonSlugController from "./controllers/TaxonSlugController";
|
import TaxonSlugController from "./controllers/TaxonSlugController";
|
||||||
|
import AutocompleteController from '@symfony/ux-autocomplete';
|
||||||
|
|
||||||
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
||||||
export const app = startStimulusApp(require.context(
|
export const app = startStimulusApp(require.context(
|
||||||
|
|
@ -23,3 +24,4 @@ export const app = startStimulusApp(require.context(
|
||||||
app.register('live', LiveController);
|
app.register('live', LiveController);
|
||||||
app.register('slug', SlugController);
|
app.register('slug', SlugController);
|
||||||
app.register('taxon-slug', TaxonSlugController);
|
app.register('taxon-slug', TaxonSlugController);
|
||||||
|
app.register('symfony--ux-autocomplete--autocomplete', AutocompleteController)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,17 @@
|
||||||
{
|
{
|
||||||
"controllers": [],
|
"controllers": {
|
||||||
|
"@symfony/ux-autocomplete": {
|
||||||
|
"autocomplete": {
|
||||||
|
"main": "dist/controller.js",
|
||||||
|
"webpackMode": "eager",
|
||||||
|
"fetch": "eager",
|
||||||
|
"enabled": true,
|
||||||
|
"autoimport": {
|
||||||
|
"tom-select/dist/css/tom-select.default.css": false,
|
||||||
|
"tom-select/dist/css/tom-select.bootstrap5.css": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"entrypoints": []
|
"entrypoints": []
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@
|
||||||
//@import "@tabler/core/src/scss/tabler-flags.scss";
|
//@import "@tabler/core/src/scss/tabler-flags.scss";
|
||||||
@import "_flags.scss";
|
@import "_flags.scss";
|
||||||
|
|
||||||
|
body {
|
||||||
|
--bs-body-bg: #{$body-bg};
|
||||||
|
--bs-tertiary-bg: #{$body-bg};
|
||||||
|
--bs-body-color: #{$body-color};
|
||||||
|
}
|
||||||
|
|
||||||
@import "alert";
|
@import "alert";
|
||||||
@import "avatar";
|
@import "avatar";
|
||||||
@import "collapse";
|
@import "collapse";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
This file is part of the Sylius package.
|
||||||
|
|
||||||
|
(c) Sylius Sp. z o.o.
|
||||||
|
|
||||||
|
For the full copyright and license information, please view the LICENSE
|
||||||
|
file that was distributed with this source code.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
|
<services>
|
||||||
|
<service id="Sylius\Bundle\AdminBundle\Autocompleter\ProductAttributeAutocompleter">
|
||||||
|
<argument>%sylius.model.product_attribute.class%</argument>
|
||||||
|
<tag name="ux.entity_autocompleter" alias="product_attribute" />
|
||||||
|
</service>
|
||||||
|
</services>
|
||||||
|
</container>
|
||||||
|
|
@ -59,5 +59,11 @@
|
||||||
<argument>Sylius\Bundle\ProductBundle\Form\Type\ProductType</argument>
|
<argument>Sylius\Bundle\ProductBundle\Form\Type\ProductType</argument>
|
||||||
<argument type="service" id="sylius.context.locale" />
|
<argument type="service" id="sylius.context.locale" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="Sylius\Bundle\AdminBundle\TwigComponent\Product\ProductAttributeAutocompleteComponent">
|
||||||
|
<call method="setLiveResponder">
|
||||||
|
<argument type="service" id="ux.live_component.live_responder"/>
|
||||||
|
</call>
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body py-4 border-bottom">
|
<div class="card-body py-4 border-bottom">
|
||||||
|
<twig:SyliusAdmin.Product.ProductAttributeAutocomplete />
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-sm-4">
|
<div class="col-12 col-sm-4">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<div {{ attributes }}>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input
|
||||||
|
name="product_attributes"
|
||||||
|
data-model="attributeCodes"
|
||||||
|
{{ stimulus_controller('symfony/ux-autocomplete/autocomplete', {
|
||||||
|
url: path('ux_entity_autocomplete', { alias: 'product_attribute' }),
|
||||||
|
}) }}
|
||||||
|
/>
|
||||||
|
<button type="button" class="btn btn-primary" data-action="live#action" data-action-name="prevent|addAttribute()">
|
||||||
|
{{ 'sylius.ui.add'|trans }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('product_attribute_autocomplete:clear', () => {
|
||||||
|
document.querySelector('input[name="product_attributes"]').tomselect.clear();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
@ -22,6 +22,7 @@ use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
||||||
use Symfony\UX\LiveComponent\Attribute\LiveAction;
|
use Symfony\UX\LiveComponent\Attribute\LiveAction;
|
||||||
use Symfony\UX\LiveComponent\Attribute\LiveArg;
|
use Symfony\UX\LiveComponent\Attribute\LiveArg;
|
||||||
|
use Symfony\UX\LiveComponent\Attribute\LiveListener;
|
||||||
use Symfony\UX\LiveComponent\Attribute\LiveProp;
|
use Symfony\UX\LiveComponent\Attribute\LiveProp;
|
||||||
use Symfony\UX\LiveComponent\DefaultActionTrait;
|
use Symfony\UX\LiveComponent\DefaultActionTrait;
|
||||||
use Symfony\UX\LiveComponent\LiveCollectionTrait;
|
use Symfony\UX\LiveComponent\LiveCollectionTrait;
|
||||||
|
|
@ -83,4 +84,18 @@ final class FormComponent
|
||||||
$this->formValues['attributes'],
|
$this->formValues['attributes'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[LiveListener('product_attribute_autocomplete:add')]
|
||||||
|
public function addAttributes(#[LiveArg] array $attributeCodes): void
|
||||||
|
{
|
||||||
|
foreach ($attributeCodes as $attributeCode) {
|
||||||
|
foreach ($this->formValues['translations'] as $localesCode => $translation) {
|
||||||
|
$this->formValues['attributes'][] = [
|
||||||
|
'attribute' => $attributeCode,
|
||||||
|
'localeCode' => $localesCode,
|
||||||
|
'value' => '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\AdminBundle\TwigComponent\Product;
|
||||||
|
|
||||||
|
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
||||||
|
use Symfony\UX\LiveComponent\Attribute\LiveAction;
|
||||||
|
use Symfony\UX\LiveComponent\Attribute\LiveProp;
|
||||||
|
use Symfony\UX\LiveComponent\ComponentToolsTrait;
|
||||||
|
use Symfony\UX\LiveComponent\DefaultActionTrait;
|
||||||
|
|
||||||
|
#[AsLiveComponent(name: 'SyliusAdmin.Product.ProductAttributeAutocomplete', template: '@SyliusAdmin/Product/_productAttributeAutocomplete.html.twig')]
|
||||||
|
final class ProductAttributeAutocompleteComponent
|
||||||
|
{
|
||||||
|
#[LiveProp(writable: true)]
|
||||||
|
public ?string $attributeCodes = null;
|
||||||
|
|
||||||
|
use ComponentToolsTrait;
|
||||||
|
use DefaultActionTrait;
|
||||||
|
|
||||||
|
#[LiveAction]
|
||||||
|
public function addAttribute(): void
|
||||||
|
{
|
||||||
|
$this->emit('product_attribute_autocomplete:add', ['attributeCodes' => explode(',', $this->attributeCodes)]);
|
||||||
|
$this->attributeCodes = '';
|
||||||
|
$this->dispatchBrowserEvent('product_attribute_autocomplete:clear');
|
||||||
|
}
|
||||||
|
}
|
||||||
12
symfony.lock
12
symfony.lock
|
|
@ -870,6 +870,18 @@
|
||||||
"templates/base.html.twig"
|
"templates/base.html.twig"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"symfony/ux-autocomplete": {
|
||||||
|
"version": "2.9999999",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "2.6",
|
||||||
|
"ref": "07d9602b7231ba355f484305d6cea58310c01741"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/routes/ux_autocomplete.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/ux-live-component": {
|
"symfony/ux-live-component": {
|
||||||
"version": "2.12",
|
"version": "2.12",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue