Squashed commit message
Some checks are pending
Telegram Mini App Shop Builder / Compute version metadata (push) Waiting to run
Telegram Mini App Shop Builder / Run Frontend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run Backend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Waiting to run
Telegram Mini App Shop Builder / Build module. (push) Blocked by required conditions
Telegram Mini App Shop Builder / release (push) Blocked by required conditions
Some checks are pending
Telegram Mini App Shop Builder / Compute version metadata (push) Waiting to run
Telegram Mini App Shop Builder / Run Frontend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run Backend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Waiting to run
Telegram Mini App Shop Builder / Build module. (push) Blocked by required conditions
Telegram Mini App Shop Builder / release (push) Blocked by required conditions
This commit is contained in:
70
.cursor/rules/form-builder.md
Normal file
70
.cursor/rules/form-builder.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# FormBuilder System Context
|
||||
|
||||
## Architectural Overview
|
||||
The FormBuilder ecosystem is a strictly typed Vue 3 application module designed to generate standard FormKit Schema JSON. It eschews internal DTOs in favor of direct schema manipulation.
|
||||
|
||||
### Core Components
|
||||
1. **FormBuilderView (`views/FormBuilderView.vue`)**:
|
||||
* **Role**: Smart container / Data fetcher.
|
||||
* **Responsibility**: Fetches form data from API (`GET /api/admin/forms/{alias}`), handles loading states, and passes data to `FormBuilder`.
|
||||
* **Contract**: Expects API response `{ data: { schema: Array, is_custom: Boolean, ... } }`.
|
||||
|
||||
2. **FormBuilder (`components/FormBuilder/FormBuilder.vue`)**:
|
||||
* **Role**: Main Orchestrator / State Owner.
|
||||
* **Responsibility**: Manages `v-model` (schema), mode switching (Visual/Code/Preview), and provides state to children.
|
||||
* **State Management**: Uses `defineModel` for `formFields` (schema) and `isCustom` (mode flag). Uses `provide('formFields')` and `provide('selectedFieldId')` for deep dependency injection.
|
||||
* **Modes**:
|
||||
* **Visual**: Drag-and-drop interface using `vuedraggable`.
|
||||
* **Code**: Direct JSON editing of the FormKit schema. Sets `isCustom = true`.
|
||||
* **Preview**: Renders the current schema using `FormKit`.
|
||||
|
||||
3. **FormCanvas (`components/FormBuilder/FormCanvas.vue`)**:
|
||||
* **Role**: Visual Editor Surface.
|
||||
* **Responsibility**: Renders the draggable list of fields.
|
||||
* **Implementation**: Uses `vuedraggable` bound to `formFields`.
|
||||
* **UX**: Implements "Ghost" and "Drag" classes for visual feedback. Handles selection logic.
|
||||
|
||||
4. **FieldsPanel (`components/FormBuilder/FieldsPanel.vue`)**:
|
||||
* **Role**: Component Palette.
|
||||
* **Responsibility**: Source of truth for available field types.
|
||||
* **Implementation**: Uses `vuedraggable` with `pull: 'clone', put: false` to spawn new fields.
|
||||
|
||||
5. **FieldSettings (`components/FormBuilder/FieldSettings.vue`)**:
|
||||
* **Role**: Property Editor.
|
||||
* **Responsibility**: Edits properties of the `selectedFieldId`.
|
||||
* **Constraint**: Must use PrimeVue components for all inputs.
|
||||
|
||||
## Data Flow & Invariants
|
||||
1. **Schema Authority**: The FormKit Schema JSON is the single source of truth. There is no "internal model" separate from the schema.
|
||||
2. **Reactivity**:
|
||||
* `formFields` is an Array of Objects.
|
||||
* Mutations must preserve reactivity. When using `v-model` or `provide/inject`, ensure array methods (splice, push, filter) are used correctly or replace the entire array reference if needed to trigger watchers.
|
||||
* **Immutability**: `useFormFields` composable uses immutable patterns (returning new array references) to ensure `defineModel` in parent detects changes.
|
||||
3. **Mode Logic**:
|
||||
* Switching to **Code** mode sets `isCustom = true`.
|
||||
* Switching to **Visual** mode sets `isCustom = false`.
|
||||
* **Safety**: Switching modes triggers JSON validation. Invalid JSON prevents mode switch.
|
||||
4. **Drag and Drop**:
|
||||
* Powered by `vuedraggable` (Sortable.js).
|
||||
* **Clone Logic**: `FieldsPanel` clones from `availableFields`. `FormCanvas` receives the clone.
|
||||
* **ID Generation**: Unique IDs are generated upon cloning/addition to ensure key stability.
|
||||
|
||||
## Naming & Conventions
|
||||
* **Tailwind**: Use `tw:` prefix for all utility classes (e.g., `tw:flex`, `tw:p-4`).
|
||||
* **Components**: PrimeVue components are the standard UI kit (Button, Panel, InputText, etc.).
|
||||
* **Icons**: FontAwesome (`fa fa-*`).
|
||||
* **Files**: PascalCase for components (`FormBuilder.vue`), camelCase for logic (`useFormFields.js`).
|
||||
|
||||
## Integration Rules
|
||||
* **Backend**: The backend stores the JSON blob directly. `FormBuilder` does not transform data before save; it emits the raw schema.
|
||||
* **API**: `useFormsStore` handles API communication.
|
||||
|
||||
## Pitfalls & Warnings
|
||||
* **vuedraggable vs @formkit/drag-and-drop**: We strictly use `vuedraggable`. Do not re-introduce `@formkit/drag-and-drop`.
|
||||
* **Watchers**: Avoid `watch` where `computed` or event handlers suffice, to prevent infinite loops in bidirectional data flow.
|
||||
* **Tailwind Config**: Do not use `@apply` with `tw:` prefixed classes in `<style>` blocks; standard CSS properties should be used if custom classes are needed.
|
||||
|
||||
## Future Modifications
|
||||
* **Adding Fields**: Update `constants/availableFields.js` and ensure `utils/fieldHelpers.js` supports the new type.
|
||||
* **Validation**: FormKit validation rules string (e.g., "required|email") is edited as a raw string in `FieldSettings`. Complex validation builders would require a new UI component.
|
||||
|
||||
Reference in New Issue
Block a user