Skip to content

Commit 3b86e39

Browse files
committed
[Studio] improvements
1 parent 270dd08 commit 3b86e39

File tree

67 files changed

+199
-379
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+199
-379
lines changed

docs/03_Development/14_Studio/01_Extending_Shipping_Rules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ class VolumeConditionChecker implements ShippingConditionCheckerInterface
267267
## Best Practices
268268

269269
1. **Prefer PHP FormTypes**: Use the schema-driven approach for all new conditions/actions
270-
2. **Use appropriate Symfony form types**: `ChoiceType` for selects, `NumberType` for numbers, `AutocompleteType` for Pimcore relations
270+
2. **Use appropriate Symfony form types**: `ChoiceType` for selects, `NumberType` for numbers, `PimcoreRelationType` for Pimcore relations
271271
3. **Use FormTypeExtensions**: To add cross-bundle fields (e.g., CoreBundle adding stores/currencies to other bundles' forms)
272272
4. **Only write React for truly special UIs**: Recursive nesting, drag-and-drop, real-time validation that can't be server-driven
273273
5. **Test with the schema endpoint**: `GET /pimcore-studio/api/coreshop-studio-form/schema/{blockPrefix}` to verify your form generates correctly

docs/03_Development/14_Studio/02_Base_Infrastructure/04_StudioFormBundle.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ import { PimcoreRelationWidget } from './PimcoreRelationWidget'
166166
167167
const registry = container.get<WidgetRegistry>(widgetRegistryServiceId)
168168
169-
registry.register('coreshop_autocomplete', (field) => ({
169+
registry.register('coreshop_pimcore_relation', (field) => ({
170170
component: PimcoreRelationWidget,
171171
props: {
172-
autocompleteClass: field.extra?.autocomplete_class,
172+
relationClass: field.extra?.relation_class,
173173
multiple: field.extra?.multiple ?? false,
174174
},
175175
}))

docs/03_Development/14_Studio/02_Base_Infrastructure/05_StudioFormBundle_Examples.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,9 @@ export const CategoryForm: React.FC<{
309309

310310
## Category 2: Special Field Types
311311

312-
### Example 4 — Pimcore Relations (AutocompleteType)
312+
### Example 4 — Pimcore Relations (PimcoreRelationType)
313313

314-
Use `AutocompleteType` to create fields that reference Pimcore Data Objects. The widget shows an autocomplete search and renders as a relation/tag widget.
314+
Use `PimcoreRelationType` to create fields that reference Pimcore Data Objects. The widget renders Pimcore's native ManyToOneRelation / ManyToManyRelation picker.
315315

316316
**PHP — FormType:**
317317

@@ -320,7 +320,7 @@ Use `AutocompleteType` to create fields that reference Pimcore Data Objects. The
320320
321321
namespace App\Form\Type;
322322
323-
use CoreShop\Bundle\StudioFormBundle\Form\Type\AutocompleteType;
323+
use CoreShop\Bundle\StudioFormBundle\Form\Type\PimcoreRelationType;
324324
use Symfony\Component\Form\AbstractType;
325325
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
326326
use Symfony\Component\Form\FormBuilderInterface;
@@ -331,10 +331,10 @@ final class FeaturedCategoriesConfigurationType extends AbstractType
331331
{
332332
$builder
333333
// Multiple Pimcore object relations
334-
->add('categories', AutocompleteType::class, [
334+
->add('categories', PimcoreRelationType::class, [
335335
'label' => 'app_condition_categories',
336-
'autocomplete_class' => 'CoreShopCategory', // Pimcore class name
337-
'multiple' => true, // Allow multiple selections
336+
'relation_class' => 'CoreShopCategory', // Pimcore class name
337+
'multiple' => true, // Allow multiple selections
338338
])
339339
->add('recursive', CheckboxType::class, [
340340
'label' => 'app_condition_recursive',
@@ -349,17 +349,17 @@ final class FeaturedCategoriesConfigurationType extends AbstractType
349349
}
350350
```
351351

352-
The `autocomplete_class` option is exposed through the schema as `extra.autocomplete_class`. The CoreBundle registers a custom widget for the `coreshop_autocomplete` block prefix that renders a `PimcoreRelationWidget`:
352+
The `relation_class` option is exposed through the schema as `extra.relation_class`. The CoreBundle registers a custom widget for the `coreshop_pimcore_relation` block prefix that renders a `PimcoreRelationWidget`:
353353

354354
```typescript
355355
// Already registered by CoreBundle — you don't need to do this yourself.
356356
// Shown here for understanding:
357357
const registry = container.get<WidgetRegistry>(widgetRegistryServiceId)
358358
359-
registry.register('coreshop_autocomplete', (field) => ({
359+
registry.register('coreshop_pimcore_relation', (field) => ({
360360
component: PimcoreRelationWidget,
361361
props: {
362-
autocompleteClass: field.extra?.autocomplete_class,
362+
relationClass: field.extra?.relation_class,
363363
multiple: field.extra?.multiple ?? false,
364364
},
365365
}))
@@ -1148,7 +1148,7 @@ This is especially impactful when a rule has many conditions/actions expanded si
11481148
| Simple entity form | `AbstractResourceType` + `coreshop.studio_form` tag | `<SchemaForm blockPrefix="..." />` |
11491149
| Add choices | `ChoiceType` or entity `ChoiceType` | Automatic |
11501150
| Add translations | `ResourceTranslationsType` | Pass `currentLocale` + `locales` |
1151-
| Add Pimcore relations | `AutocompleteType` | Automatic (widget registered) |
1151+
| Add Pimcore relations | `PimcoreRelationType` | Automatic (widget registered) |
11521152
| Add dynamic lists | `CollectionType` with `allow_add`/`allow_delete` | Automatic |
11531153
| Group fields in sections | `FormSchemaEnricherInterface` + `SectionSchema` | Automatic |
11541154
| Group fields in tabs | `FormSchemaEnricherInterface` + `TabSchema` | Automatic |

docs/03_Development/14_Studio/04_ProductBundle/01_Product_Price_Rules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ Note: There are no `conditions/` or `actions/` subdirectories — all condition/
322322
## Best Practices
323323

324324
1. **Prefer PHP FormTypes**: Use the schema-driven approach for all new conditions/actions
325-
2. **Use appropriate Symfony form types**: `ChoiceType` for selects, `NumberType` for numbers, `AutocompleteType` for Pimcore relations
325+
2. **Use appropriate Symfony form types**: `ChoiceType` for selects, `NumberType` for numbers, `PimcoreRelationType` for Pimcore relations
326326
3. **Test with both rule types**: Ensure your extension works for both Product Price Rules and Product Specific Price Rules
327327
4. **Only write React for truly special UIs**: Recursive nesting, drag-and-drop, etc.
328328
5. **Test with the schema endpoint**: `GET /pimcore-studio/api/coreshop-studio-form/schema/{blockPrefix}` to verify your form generates correctly

src/CoreShop/Bundle/AddressBundle/Resources/assets/pimcore-studio/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
"license": "CCL",
1414
"private": true,
1515
"dependencies": {
16-
"@coreshop/resource": "*",
17-
"@coreshop/studio-form": "*",
1816
"@pimcore/studio-ui-bundle": "1.0.0-canary.20251119-143005-1b35b01",
1917
"@reduxjs/toolkit": "^2.0.1",
2018
"antd": "^5.12.0",
2119
"immer": "^10.1.1",
2220
"react": "18.3.x",
2321
"react-dom": "18.3.x",
2422
"react-redux": "^9.0.4",
25-
"zustand": "^5.0.7"
23+
"zustand": "^5.0.7",
24+
"@coreshop/resource": "file:../../../../ResourceBundle/Resources/assets/pimcore-studio",
25+
"@coreshop/studio-form": "*"
2626
}
2727
}

src/CoreShop/Bundle/AddressBundle/Resources/assets/pimcore-studio/src/modules/address-identifiers/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { EntityApi } from '@coreshop/resource/src/entities/api'
22

3-
export interface AddressIdentifierDetail {
3+
export interface AddressIdentifierDetail extends Record<string, any> {
44
id: number
55
name: string
66
active: boolean

src/CoreShop/Bundle/AddressBundle/Resources/assets/pimcore-studio/src/modules/countries/CountryForm.tsx

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,15 @@
1313
*/
1414

1515
import React from 'react'
16-
import { SchemaForm } from '@coreshop/studio-form/src/schema-adapter'
16+
import { SchemaForm, type SchemaFormProps } from '@coreshop/studio-form/src/schema-adapter'
1717
import type { CountryDetail } from './api'
1818

19-
export interface CountryFormProps {
20-
data?: CountryDetail
21-
onChange: (draft: Partial<CountryDetail>) => void
22-
currentLocale?: string
23-
locales?: string[]
24-
}
25-
26-
/**
27-
* Country Form Component
28-
*
29-
* Uses SchemaForm pattern for composable, extensible form configuration.
30-
* Base form is defined in AddressBundle, extensions added by CoreBundle and others.
31-
*/
32-
export const CountryForm: React.FC<CountryFormProps> = ({
33-
data,
34-
onChange,
35-
currentLocale,
36-
}) => {
19+
export const CountryForm: React.FC<SchemaFormProps<CountryDetail>> = (props) => {
3720
return (
3821
<div style={{ padding: 12 }}>
3922
<SchemaForm<CountryDetail>
23+
{...props}
4024
blockPrefix="coreshop_country"
41-
data={data}
42-
onChange={onChange}
43-
currentLocale={currentLocale}
4425
/>
4526
</div>
4627
)

src/CoreShop/Bundle/AddressBundle/Resources/assets/pimcore-studio/src/modules/countries/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { EntityApi } from '@coreshop/resource/src/entities'
22

3-
export interface CountryDetail {
3+
export interface CountryDetail extends Record<string, any> {
44
id: number
55
name: string
66
active: boolean

src/CoreShop/Bundle/AddressBundle/Resources/assets/pimcore-studio/src/modules/states/StateForm.tsx

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,15 @@
1313
*/
1414

1515
import React from 'react'
16-
import { SchemaForm } from '@coreshop/studio-form/src/schema-adapter'
16+
import { SchemaForm, type SchemaFormProps } from '@coreshop/studio-form/src/schema-adapter'
1717
import type { StateDetail } from './api'
1818

19-
export interface StateFormProps {
20-
data?: StateDetail
21-
onChange: (draft: Partial<StateDetail>) => void
22-
currentLocale?: string
23-
locales?: string[]
24-
}
25-
26-
/**
27-
* State Form Component
28-
*
29-
* Uses SchemaForm pattern for composable, extensible form configuration.
30-
* Base form is defined in AddressBundle, extensions can be added by other bundles.
31-
*/
32-
export const StateForm: React.FC<StateFormProps> = ({
33-
data,
34-
onChange,
35-
currentLocale,
36-
}) => {
19+
export const StateForm: React.FC<SchemaFormProps<StateDetail>> = (props) => {
3720
return (
3821
<div style={{ padding: 12 }}>
3922
<SchemaForm<StateDetail>
23+
{...props}
4024
blockPrefix="coreshop_state"
41-
data={data}
42-
onChange={onChange}
43-
currentLocale={currentLocale}
4425
/>
4526
</div>
4627
)

src/CoreShop/Bundle/AddressBundle/Resources/assets/pimcore-studio/src/modules/states/StateManager.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,7 @@ export const StateManager: React.FC = () => {
3838
return null
3939
}}
4040
applyGroup={(data, groupId) => ({ ...data, country: groupId ?? undefined } as StateDetail)}
41-
buildSavePayload={(data) => ({
42-
id: data.id,
43-
name: data.name,
44-
active: data.active,
45-
isoCode: data.isoCode,
46-
country: data.country,
47-
translations: data.translations
48-
})}
41+
buildSavePayload={(data) => data}
4942
onAdd={async (groupId?: number) => await new Promise<number>((resolve) => {
5043
modal.input({
5144
title: t('coreshop_state_add', { defaultValue: 'Add State' }),

0 commit comments

Comments
 (0)