start of ai-based development
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
---
|
||||
name: elixforms-common-library
|
||||
description: >
|
||||
Documentazione della libreria condivisa common/ del progetto elixForms.
|
||||
Descrive i componenti ElixForms, il pattern di form field factory,
|
||||
le interfacce TypeScript, i tipi, e l'helper per i query parameter.
|
||||
Attiva questa skill quando lavori sui componenti condivisi, crei nuovi tipi di campo,
|
||||
modifichi la gestione dello stato del form, o integri con la piattaforma elixForms.
|
||||
---
|
||||
|
||||
# Libreria Common elixForms
|
||||
|
||||
## Panoramica
|
||||
|
||||
La cartella `react/common/` contiene la libreria condivisa di componenti React/TypeScript usata da tutte le pagine custom. È basata su **Fluent UI React v8** e implementa un sistema di form con campi dinamici.
|
||||
|
||||
## Architettura dei Componenti
|
||||
|
||||
```
|
||||
ElixFormsComponentAbstract (abstract class, extends React.Component)
|
||||
└── ElixFormsComponent (classe concreta, exported as ElixFormsReact)
|
||||
└── Usata nelle pagine come `new ElixForms.ElixFormsReact(props)`
|
||||
```
|
||||
|
||||
### Gerarchia delle classi
|
||||
|
||||
1. **`ElixFormsComponentAbstract`** (`ElixFormsComponentAbstract.tsx`)
|
||||
- Classe astratta che estende `React.Component<IElixFormsComponentProperties, IElixFormsComponentFormState>`
|
||||
- Contiene tutta la logica di creazione dei campi form (factory methods)
|
||||
- Gestisce lo state del form (`formData: { [key: string]: any }`)
|
||||
- Implementa `render()` che genera `<form>` con action POST verso elixForms
|
||||
|
||||
2. **`ElixFormsComponent`** (`ElixFormsComponent.tsx`)
|
||||
- Classe concreta che estende `ElixFormsComponentAbstract`
|
||||
- Esportata come `ElixFormsReact` per uso nelle pagine
|
||||
- Attualmente vuota (la logica è nell'abstract)
|
||||
|
||||
## Interfacce TypeScript
|
||||
|
||||
### `IElixFormsComponentProperties` (Props)
|
||||
```typescript
|
||||
interface IElixFormsComponentProperties {
|
||||
description: string;
|
||||
isDarkTheme: boolean;
|
||||
environmentMessage: string;
|
||||
hasTeamsContext: boolean;
|
||||
userDisplayName: string;
|
||||
additionalFieldsJson?: string; // JSON schema per campi dinamici
|
||||
customFormFieldsConfiguration?: ( // Callback con factory per campi custom
|
||||
formFieldFactory: IElixFormsComponentCustomFormFieldFactory
|
||||
) => JSX.Element;
|
||||
}
|
||||
```
|
||||
|
||||
### `IElixFormsComponentFormState` (State)
|
||||
```typescript
|
||||
interface IElixFormsComponentFormState {
|
||||
formData: { [key: string]: any };
|
||||
}
|
||||
```
|
||||
|
||||
### `IElixFormsComponentCustomFormFieldFactory` (Form Field Factory)
|
||||
```typescript
|
||||
type IElixFormsComponentCustomFormFieldFactory = {
|
||||
createBooleanInput(name: string, label: string, required?: boolean): JSX.Element;
|
||||
createCheckboxInput(name: string, label: string, options: ElixFormsCheckboxOption[]): JSX.Element;
|
||||
createDropdownInput(name: string, label: string, options: ElixFormsDropdownOption[], required?: boolean): JSX.Element;
|
||||
createHiddenInput(name: string): JSX.Element;
|
||||
createNumberInput(name: string, label: string, required?: boolean): JSX.Element;
|
||||
createRadioInput(name: string, label: string, options: ElixFormsRadioOption[], required?: boolean): JSX.Element;
|
||||
createTextInput(name: string, label: string, required?: boolean): JSX.Element;
|
||||
createTextAreaInput(name: string, label: string, required?: boolean): JSX.Element;
|
||||
};
|
||||
```
|
||||
|
||||
### Tipi per le Opzioni (`ElixFormsTypes.tsx`)
|
||||
```typescript
|
||||
type ElixFormsCheckboxOption = { value: number; label: string; required?: boolean };
|
||||
type ElixFormsDropdownOption = { value: number; label: string };
|
||||
type ElixFormsRadioOption = { value: number; label: string };
|
||||
```
|
||||
|
||||
## Form Field Factory Pattern
|
||||
|
||||
Le pagine usano il pattern **Custom Form Field Factory** per dichiarare i campi del form:
|
||||
|
||||
```jsx
|
||||
// In App.jsx della pagina
|
||||
var myElixFormsReact = new ElixForms.ElixFormsReact({
|
||||
// ...props...
|
||||
customFormFieldsConfiguration: (formFieldFactory) => (
|
||||
<>
|
||||
{formFieldFactory.createDropdownInput("COL0015", "Goals", [...options], true)}
|
||||
{formFieldFactory.createTextInput("COL0002", "Campo STRING", true)}
|
||||
{formFieldFactory.createTextAreaInput("COL0003", "Campo TEXTAREA", true)}
|
||||
{formFieldFactory.createBooleanInput("COL0004", "Campo BOOLEAN", true)}
|
||||
{formFieldFactory.createRadioInput("COL0005", "Campo RADIO", [...options], true)}
|
||||
{formFieldFactory.createCheckboxInput("COL0006", "Campo CHECKBOX", [...options])}
|
||||
</>
|
||||
)
|
||||
});
|
||||
```
|
||||
|
||||
### Tipi di Campo Supportati
|
||||
|
||||
| Metodo Factory | Componente FluentUI | HTML Output |
|
||||
|---|---|---|
|
||||
| `createTextInput` | `TextField` | Text input |
|
||||
| `createTextAreaInput` | `TextField` (multiline) | Textarea |
|
||||
| `createNumberInput` | `TextField` (type=number) | Number input |
|
||||
| `createBooleanInput` | `ChoiceGroup` (Sì/No) | Radio buttons |
|
||||
| `createRadioInput` | `ChoiceGroup` | Radio buttons |
|
||||
| `createCheckboxInput` | `Checkbox` + hidden input | Checkboxes |
|
||||
| `createDropdownInput` | `Dropdown` | Select dropdown |
|
||||
| `createHiddenInput` | Native `<input type="text">` | Hidden field |
|
||||
|
||||
## ElixFormsElement (Wrapper Layout)
|
||||
|
||||
`ElixFormsElement` è una classe che incapsula label + input in un layout a due colonne compatibile con il design system elixForms:
|
||||
|
||||
```tsx
|
||||
class ElixFormsElement {
|
||||
constructor(labelElement: ReactElement, inputElement: ReactElement, separator?: string);
|
||||
render(): JSX.Element;
|
||||
}
|
||||
```
|
||||
|
||||
Genera markup con classi CSS specifiche di elixForms:
|
||||
- `.iuFieldContainer` → container del campo
|
||||
- `.attrDisplay_left`, `.attrDisplay_label` → colonna label
|
||||
- `.attrDisplay_right`, `.attrDisplay_input` → colonna input
|
||||
|
||||
## QueryParamHelper
|
||||
|
||||
Utility statica per leggere parametri dalla URL corrente:
|
||||
|
||||
```typescript
|
||||
class QueryParamHelper {
|
||||
static getCheckedFromQuery(paramName: string): number[]; // Per checkbox (valori separati da virgola)
|
||||
static getOptionFromQuery(paramName: string): number | undefined; // Per radio/dropdown
|
||||
static getBooleanFromQuery(paramName: string): boolean | undefined;// Per boolean
|
||||
static getDecodedTextFromQuery(paramName: string): string | undefined; // Per testo (URI decoded)
|
||||
}
|
||||
```
|
||||
|
||||
Usato per pre-popolare i campi form con i valori passati via query string dalla piattaforma elixForms.
|
||||
|
||||
## Campi Obbligatori elixForms
|
||||
|
||||
Il componente abstract gestisce automaticamente questi parametri come hidden inputs:
|
||||
- `RWE2_MODULE_ID`
|
||||
- `RWE2_REQUEST_ID`
|
||||
- `custom-workflow-back-url`
|
||||
- `custom-workflow-generic-id`
|
||||
- `custom-workflow-current-tabrel-genid`
|
||||
- `custom-workflow-source-field`
|
||||
- `crc`
|
||||
- `MODULE_TESTMODE_KEY`
|
||||
- `ELANG`
|
||||
|
||||
## Note Importanti
|
||||
|
||||
- Lo **state management** attuale usa `React.Component` class-based con `this.state` e `this.setState`
|
||||
- I checkbox gestiscono un `Map<string, number[]>` interno per tracciare i valori selezionati
|
||||
- Il form fa POST a `https://procedure.unipr.it/rwe2/ComeBackToElixAndSave`
|
||||
- L'encoding charset è `ISO-8859-1` per compatibilità con il backend
|
||||
- La libreria usa **SCSS modules** per gli stili (`ElixFormsComponent.module.scss`)
|
||||
- Il package `common` è di tipo `commonjs` (diverso dalle pagine che sono `module`)
|
||||
Reference in New Issue
Block a user