# AccountForm



The `AccountForm` component is a dynamic form used for creating or
updating an account. It renders form fields based on a provided data
model, allowing for flexible account structures. The form can be toggled
between “create” and “update” modes based on the presence of an
`account` object.

Usage [#usage]

Integrate `AccountForm` by providing it with a resolved data model, an
account type, and a submit handler. The component is built on top of
`@jsonforms/react` and handles rendering and state management
internally.

```ts
import { AccountForm } from '@socotra/ec-react-components';
import { DataModel, AccountResponse } from '@socotra/ec-react-schemas';

// Example Usage
const MyComponent = ({ dataModel, account }: { dataModel: DataModel, account?: AccountResponse }) => {
  const handleSubmit = (data) => {
    console.log('Form submitted:', data);
    // Handle API call to create or update the account
  };

  return (
    <AccountForm
      dataModel={dataModel}
      accountType="personal"
      account={account}
      handleSubmit={handleSubmit}
      submitButtonText={account ? 'Update Account' : 'Create Account'}
    />
  );
};
```

Props [#props]

The component accepts the following props:

| Prop                         | Type                                                                                                   | Description                                                                                                   | Default      |
| ---------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------ |
| `dataModel`                  | `DataModel`                                                                                            | The resolved data model object containing account configurations and data types.                              | **Required** |
| `accountType`                | `keyof AccountConfigRecord`                                                                            | The specific account type from the data model to render the form for.                                         | **Required** |
| `handleSubmit`               | `(data: AccountCreateRequest \| AccountUpdateRequest) => void`                                         | Callback function triggered on form submission. The argument type depends on whether `account` is provided.   | **Required** |
| `account`                    | `AccountResponse`                                                                                      | An optional account object. If provided, the form enters “update” mode.                                       | `undefined`  |
| `isSubmitting`               | `boolean`                                                                                              | When true, disables the form fields and submit button, indicating a submission is in progress.                | `false`      |
| `disabled`                   | `boolean`                                                                                              | When true, disables the entire form.                                                                          | `false`      |
| `preventFormResetOnDisabled` | `boolean`                                                                                              | If `false`, the form’s data will reset to initial values when `disabled` becomes true.                        | `true`       |
| `hideSubmitButton`           | `boolean`                                                                                              | If `true`, the submit button will not be rendered.                                                            | `false`      |
| `submitButtonText`           | `string`                                                                                               | Custom text for the submit button.                                                                            | `'Update'`   |
| `hideAdvancedFields`         | `boolean`                                                                                              | If `true`, hides the expandable “Advanced Fields” section.                                                    | `false`      |
| `validateOnSubmit`           | `boolean`                                                                                              | If `true`, validation is run on submit and submission is blocked if invalid.                                  | `false`      |
| `id`                         | `string`                                                                                               | A unique ID for the form wrapper element.                                                                     | `undefined`  |
| `titles`                     | `object`                                                                                               | An object to override default labels for advanced fields and other parts of the form.                         | `{}`         |
| `dependencyMap`              | `DependencyMapResponse`                                                                                | Optional map of field dependencies, required to enable constraint evaluation for the account form.            | `undefined`  |
| `getEvaluatedConstraints`    | `(request: AccountEvaluateConstraintsRequest) => Promise&lt;EvaluateConstraintsResponse \| undefined>` | Optional async function to call the backend for constraint evaluation. Required for the feature to be active. | `undefined`  |

State Management [#state-management]

`AccountForm` manages its state internally using React’s `useState`
hook. It holds the form data in a state variable that is updated by the
underlying `JsonForms` component via its `onChange` callback. It
does not use an external form library like `react-hook-form`.

Constraint Evaluation [#constraint-evaluation]

This form supports a powerful constraint evaluation system to create
dynamic relationships between fields.

* **Purpose:** To automatically calculate or update the values of
  certain fields based on user input in other fields, without requiring
  a full form submission. For example, selecting a specific “Region”
  could automatically populate a “Tax Rate” field.
* **Activation:** The feature is enabled by providing both the
  `dependencyMap` and `getEvaluatedConstraints` props.
* **Mechanism:**
  1. The `dependencyMap` tells the form which fields depend on others.
  2. When a user changes a field that is a dependency for another, a
     `useEffect` hook is triggered.
  3. This hook calls the `getEvaluatedConstraints` function with a
     payload of the changed data.
  4. The backend service evaluates the data and returns a
     `EvaluateConstraintsResponse` containing the new values for any
     dependent fields.
  5. This response is stored in the `evaluatedConstraints` state,
     which triggers a re-render.
  6. The `dataModelToJSONSchema` utility uses this response to update
     the JSON Schema, making the calculated fields read-only and
     displaying their new values.

Validation [#validation]

Form validation is handled by [Ajv ](https://ajv.js.org/), a JSON
Schema validator.

* A JSON Schema is dynamically generated from the `dataModel` prop
  using the `dataModelToJSONSchema` utility.
* Custom validation formats and keywords are added to the Ajv instance.
* Validation can be configured to run when the user clicks the submit
  button by setting `validateOnSubmit={true}`.
* Error messages are translated into a user-friendly format using the
  `translateError` utility.

Labels and Translations [#labels-and-translations]

The text for UI labels and validation messages can be customized.

**UI Labels**

Labels for sections and fields can be overridden by passing a `titles`
object prop.

| Key                          | Description                                     | Default Value                     |
| ---------------------------- | ----------------------------------------------- | --------------------------------- |
| `seeAdvancedDetails`         | Title for the collapsible “Advanced” section.   | `'See Advanced Details'`          |
| `autoRenewalPlanName`        | Label for the “Auto-Renewal Plan” field.        | `'Auto-renewal Plan Name'`        |
| `delinquencyPlanName`        | Label for the “Delinquency Plan” field.         | `'Delinquency Plan Name'`         |
| `excessCreditPlanName`       | Label for the “Excess Credit Plan” field.       | `'Excess Credit Plan Name'`       |
| `shortfallTolerancePlanName` | Label for the “Shortfall Tolerance Plan” field. | `'Shortfall Tolerance Plan Name'` |
| `billingLevel`               | Label for the “Billing Level” field.            | `'Billing Level'`                 |
| `invoiceDocument`            | Label for the “Invoice Document” field.         | `'Invoice Document'`              |
| `installmentPlanName`        | Label for the “Installment Plan” field.         | `'Installment Plan Name'`         |
| `truthyLabel`                | Text for a “true” boolean value.                | `'Yes'`                           |
| `falsyLabel`                 | Text for a “false” boolean value.               | `'No'`                            |
