# User Interface Layer

> The `src/<Module>/…` paths used throughout this document are drawn from a
> representative CG Mobile customer workspace. Your workspace may use different
> module names, but the folder structure (`DS/`, `BO/`, `LO/`, `PR/`, `UI/`)
> and naming conventions are identical.

## Overview

User Interface (UI) definitions describe how data is presented to users through screens, forms, and lists. They bind to ProcessContext variables from the Process layer and define responsive layouts for different device types (phone, tablet, desktop).

## User Interface Fundamentals

### Purpose

User Interface (UI) definitions serve as the presentation layer that:

-   Define screen layouts and visual structure
-   Bind UI controls to ProcessContext variables (BOs, LOs, properties)
-   Support responsive layouts for phone, tablet, and desktop
-   Handle user interactions through events
-   Display localized labels and messages
-   Format data for display (dates, numbers, currencies)
-   Define menu items and navigation actions

### Directory Structure

```
src/
├── Call/
│   └── PR/
│       └── Call_AccountReceivables/
│           ├── Call_AccountReceivablesProcess.processflow.xml
│           └── Call_AccountReceivablesUI.userinterface.xml
└── Visit/
    └── PR/
        ├── Visit_Info/
        │   ├── Visit_InfoProcess.processflow.xml
        │   └── Visit_InfoUI.userinterface.xml
        └── Visit_Reschedule/
            ├── Visit_RescheduleProcess.processflow.xml
            └── Visit_RescheduleUI.userinterface.xml
```

**Note:** UI files are co-located with their Process definitions in the PR/ directory.

## UI XML Structure

### Root Element

```xml
<UIDescription
  name="Call::AccountReceivablesUI"       <!-- UI identifier (namespace::name) -->
  schemaVersion="0.0.0.5"                 <!-- Schema version -->
  simpleEditorOnly="false"                <!-- Designer constraint -->
>
```

### Key Elements

| Element        | Description                          | Required |
| -------------- | ------------------------------------ | -------- |
| `<Page>`       | Root container defining page pattern | Yes      |
| `<PageHeader>` | Title, menu items, header bindings   | Yes      |
| `<Section>`    | Major page sections                  | Yes      |
| `<Area>`       | Content areas within sections        | Yes      |
| `<Bindings>`   | Data bindings to ProcessContext      | Yes      |
| `<Events>`     | User interaction handlers            | No       |
| `<MenuItems>`  | Action buttons in header             | No       |

## Example 1: List View - Call_AccountReceivablesUI

**Location:** `src/Call/PR/Call_AccountReceivables/Call_AccountReceivablesUI.userinterface.xml`
**Purpose:** Display a list of account receivables with responsive layouts

### Complete UI XML

```xml
<UIDescription name="Call::AccountReceivablesUI" schemaVersion="0.0.0.5">
  <Page pagePattern="SingleSectionPage" cachable="false">
    <PageHeader>
      <Bindings>
        <Resource target="title" type="Label" id="AccountReceivableId" defaultLabel="Account Receivables" bindingMode="ONE_TIME" />
      </Bindings>
    </PageHeader>
    <Section sectionName="masterSection" sectionPattern="SingleAreaSection">
      <Area areaName="mainArea" areaPattern="SingleElementArea">
        <GroupedList name="MasterList" dataSource="ProcessContext::AccountReceivableList">
          <Items name="Items" itemPattern="AccountReceivablesPattern">
            <ItemListLayout>
              <!-- Default (Desktop) Layout -->
              <Default>
                <Col width="10em">
                  <Row layoutType="itemIdentifier" bindingId="ExternalIdInvoiceInfo" />
                </Col>
                <Col width="2.5em">
                  <Row layoutType="itemSecondary" bindingId="ReceiptDateLabel" />
                  <Row layoutType="itemSecondary" bindingId="DueDateLabel" />
                </Col>
                <Col width="3em">
                  <Row layoutType="itemValueSmall" bindingId="ReceiptDateText" />
                  <Row layoutType="itemValueSmall" bindingId="DueDateText" />
                </Col>
                <Col width="2em">
                  <Row layoutType="itemSecondary itemCenter" bindingId="AmountLabel" />
                  <Row layoutType="itemSecondary itemCenter" bindingId="AmountOpenLabel" />
                </Col>
                <Col width="3em" layoutType="itemRight">
                  <Row layoutType="itemIdentifier itemRight" bindingId="Amount" />
                  <Row layoutType="itemIdentifier itemRight" bindingId="AmountOpen" />
                </Col>
                <Col width="0.5em" height="1em" layoutType="Image" bindingId="AccountReceivableIcon" />
              </Default>

              <!-- Tablet Layout -->
              <Tablet>
                <Default>
                  <Col width="10em">
                    <Row layoutType="itemIdentifier" bindingId="ExternalIdInvoiceInfo" />
                  </Col>
                  <Col width="2.5em">
                    <Row layoutType="itemLabel" bindingId="ReceiptDateLabel" />
                    <Row layoutType="itemLabel" bindingId="DueDateLabel" />
                  </Col>
                  <Col width="3em">
                    <Row layoutType="itemValue" bindingId="ReceiptDateText" />
                    <Row layoutType="itemValue" bindingId="DueDateText" />
                  </Col>
                  <Col width="2em">
                    <Row layoutType="itemLabel itemCenter" bindingId="AmountLabel" />
                    <Row layoutType="itemLabel itemCenter" bindingId="AmountOpenLabel" />
                  </Col>
                  <Col width="3em" layoutType="itemRight">
                    <Row layoutType="itemIdentifier itemRight" bindingId="Amount" />
                    <Row layoutType="itemIdentifier itemRight" bindingId="AmountOpen" />
                  </Col>
                  <Col width="0.5em" height="1em" layoutType="Image" bindingId="AccountReceivableIcon" />
                </Default>
              </Tablet>

              <!-- Phone Layout -->
              <Phone>
                <Default>
                  <Col width="9em">
                    <Row layoutType="itemIdentifier itemLeft" bindingId="ExternalIdInvoiceInfo" />
                    <Row>
                      <Col flex="1" layoutType="itemSecondaryCockpit itemLeft" bindingId="ReceiptDateLabel" />
                      <Col flex="1" layoutType="itemValue itemLeft" bindingId="ReceiptDateText" />
                    </Row>
                    <Row>
                      <Col flex="1" layoutType="itemSecondaryCockpit itemLeft" bindingId="DueDateLabel" />
                      <Col flex="1" layoutType="itemValue itemLeft" bindingId="DueDateText" />
                    </Row>
                  </Col>
                  <Col width="4em">
                    <Row layoutType="itemLabel itemRight" bindingId="AmountLabel" />
                    <Row layoutType="itemIdentifier itemRight" bindingId="Amount" />
                    <Row layoutType="itemLabel itemRight" bindingId="AmountOpenLabel" />
                    <Row layoutType="itemIdentifier itemRight" bindingId="AmountOpen" />
                  </Col>
                  <Col width="0.5em" height="0.5em" layoutType="Image" bindingId="AccountReceivableIcon" />
                </Default>
              </Phone>
            </ItemListLayout>

            <Bindings>
              <Binding target="Amount" type="Decimal" binding=".amount" formatV2="10.2" bindingMode="ONE_WAY" />
              <Binding target="AmountOpen" type="Decimal" binding=".amountOpen" formatV2="10.2" bindingMode="ONE_WAY" />
              <Binding target="AccountReceivableIcon" type="Image" imageType=".svg" binding=".accountReceivableIcon" bindingMode="ONE_WAY" />
              <Binding target="ExternalIdInvoiceInfo" type="Text" binding=".externalIdInvoiceInfo" bindingMode="ONE_WAY" />
              <Binding target="DueDateText" type="Text" binding=".dueDateText" bindingMode="ONE_WAY" />
              <Binding target="ReceiptDateText" type="Text" binding=".receiptDateText" bindingMode="ONE_WAY" />
              <Resource target="AmountLabel" type="Label" defaultLabel="Amount" id="AmountLabelId" />
              <Resource target="AmountOpenLabel" type="Label" defaultLabel="Open" id="AmountOpenLabelId" />
              <Resource target="DueDateLabel" type="Label" defaultLabel="Due Date" id="DueDateLabelId" />
              <Resource target="ReceiptDateLabel" type="Label" defaultLabel="Receipt Date" id="ReceiptDateLabelId" />
            </Bindings>
          </Items>
        </GroupedList>
      </Area>
    </Section>
  </Page>
</UIDescription>
```

### Analysis

#### Page Structure

```xml
<Page pagePattern="SingleSectionPage" cachable="false">
```

-   **pagePattern:** Template for page layout
    -   `SingleSectionPage` - One main section
    -   `SingleSectionDialogPage` - Dialog-style page
    -   `TabbedSectionPage` - Multiple tabs
-   **cachable:** Whether page state can be cached

#### GroupedList Control

```xml
<GroupedList name="MasterList" dataSource="ProcessContext::AccountReceivableList">
```

-   **dataSource:** Binds to ProcessContext LO
-   Automatically iterates through list items
-   Each item rendered using ItemListLayout

#### Responsive Layouts

**Three layout definitions:**

1. **Default** - Desktop/browser
2. **Tablet** - Tablet devices
3. **Phone** - Mobile phones

The framework automatically detects the device and renders the appropriate layout.

#### Column/Row Grid System

```xml
<Col width="10em">
  <Row layoutType="itemIdentifier" bindingId="ExternalIdInvoiceInfo" />
</Col>
<Col width="3em">
  <Row layoutType="itemValueSmall" bindingId="ReceiptDateText" />
  <Row layoutType="itemValueSmall" bindingId="DueDateText" />
</Col>
```

-   **Col:** Column container with width
-   **Row:** Content row with layout type
-   **layoutType:** Styling class (itemIdentifier, itemValue, itemLabel, etc.)
-   **bindingId:** Reference to binding definition

**Width Units:**

-   `em` - Relative to font size
-   `%` - Percentage of container
-   `flex` - Flexible sizing

#### Data Bindings

```xml
<Binding target="Amount" type="Decimal" binding=".amount" formatV2="10.2" bindingMode="ONE_WAY" />
```

**Binding Attributes:**

-   **target:** UI element identifier (referenced by bindingId)
-   **type:** Data type (Text, Decimal, Date, Image, etc.)
-   **binding:** Path to data (`.amount` = current list item's amount property)
-   **formatV2:** Formatting template (10.2 = 10 digits, 2 decimals)
-   **bindingMode:** ONE_WAY (read-only) or TWO_WAY (editable)

**Binding Path Patterns:**

-   `.propertyName` - Current item property (in list context)
-   `ProcessContext::VariableName` - Process variable
-   `ProcessContext::BoName.propertyName` - BO property
-   `ProcessContext::LoName.propertyName` - LO property

#### Resource Bindings (Labels)

```xml
<Resource target="AmountLabel" type="Label" defaultLabel="Amount" id="AmountLabelId" />
```

-   **Resource:** Localized text
-   **defaultLabel:** Fallback if translation missing
-   **id:** Lookup key in localization files

## Example 2: Form View (Read-Only) - Visit_InfoUI

**Location:** `src/Visit/PR/Visit_Info/Visit_InfoUI.userinterface.xml`
**Purpose:** Display visit information in a form layout

### Complete UI XML

```xml
<UIDescription name="Visit::InfoUI" schemaVersion="0.0.0.5" simpleEditorOnly="true">
  <Page pagePattern="SingleSectionDialogPage" onBackDiscard="true">
    <PageHeader>
      <Bindings>
        <Resource target="title" type="Label" id="VisiInfoId" defaultLabel="Visit Information" bindingMode="ONE_TIME" />
      </Bindings>
    </PageHeader>
    <Section sectionName="masterSection">
      <Area areaName="mainArea" areaPattern="GroupedElementsArea">

        <!-- Visit Information Group -->
        <GroupElement name="VisitInformation">
          <Bindings>
            <Resource target="Title" type="Label" id="VisitInfo" defaultLabel="Visit Information" />
          </Bindings>
          <InputArea name="RetailStore" disabled="true">
            <Bindings>
              <Resource target="Label" type="Label" defaultLabel="Customer" id="RetailStoreId" />
              <Binding target="Value" type="Text" binding="ProcessContext::RetailStoreDetail.name" bindingMode="ONE_WAY" />
            </Bindings>
          </InputArea>
          <InputArea name="VisitStatus" disabled="true">
            <Bindings>
              <Resource target="Label" type="Label" defaultLabel="Visit Status" id="VisitStatusId" />
              <Binding target="Value" type="Text" binding="ProcessContext::VisitBo.status.text" bindingMode="ONE_WAY" />
            </Bindings>
          </InputArea>
          <Merger name="Time Merger" pattern="twoInputControls" labelHandling="Combined" leftRatio="5" rightRatio="5">
            <TimePickerField name="TimeFrom" disabled="true">
              <Bindings>
                <Resource target="Label" type="Label" defaultLabel="Time From/Thru" id="VisitPlannedTimeId" />
                <Binding target="Value" binding="ProcessContext::visitBo.plannedStartTime" bindingMode="ONE_WAY" />
              </Bindings>
            </TimePickerField>
            <TimePickerField name="TimeThru" disabled="true">
              <Bindings>
                <Binding target="Value" binding="ProcessContext::visitBo.plannedEndTime" bindingMode="ONE_WAY" />
              </Bindings>
            </TimePickerField>
          </Merger>
        </GroupElement>

        <!-- Address Group -->
        <GroupElement name="Address">
          <Bindings>
            <Resource target="Title" type="Label" id="AddressId" defaultLabel="Address" />
          </Bindings>
          <InputArea name="MainAddress" disabled="true">
            <Bindings>
              <Resource target="Label" type="Label" defaultLabel="Main Address" id="MainAddressId" />
              <Binding target="Value" type="Text" binding="ProcessContext::RetailStoreAddress.street" bindingMode="ONE_WAY" />
            </Bindings>
          </InputArea>
          <InputArea name="Zip City" disabled="true">
            <Bindings>
              <Resource target="Label" type="Label" id="ZipCity" defaultLabel="Zip City" />
              <Binding target="Value" binding="ProcessContext::RetailStoreAddress.zipCodeAndCity" bindingMode="ONE_WAY" />
            </Bindings>
          </InputArea>
        </GroupElement>

        <!-- Task Group -->
        <GroupElement name="Task">
          <Bindings>
            <Resource target="Title" type="Label" id="TaskId" defaultLabel="Task" />
          </Bindings>
          <InputAreaMultiLine name="Completed" disabled="true" noOfRows="2">
            <Bindings>
              <Resource target="Label" type="Label" defaultLabel="Completed" id="CompletedTasksId" />
              <Binding target="Value" type="Text" binding="ProcessContext::CompletedTasks" bindingMode="ONE_WAY" />
            </Bindings>
          </InputAreaMultiLine>
          <InputAreaMultiLine name="InProgress" disabled="true" noOfRows="2">
            <Bindings>
              <Resource target="Label" type="Label" defaultLabel="InProgress" id="InProgressId" />
              <Binding target="Value" type="Text" binding="ProcessContext::InProgressTasks" bindingMode="ONE_WAY" />
            </Bindings>
          </InputAreaMultiLine>
        </GroupElement>

      </Area>
    </Section>
  </Page>
</UIDescription>
```

### Analysis

#### GroupedElementsArea Pattern

```xml
<Area areaName="mainArea" areaPattern="GroupedElementsArea">
  <GroupElement name="VisitInformation">
  <GroupElement name="Address">
  <GroupElement name="Task">
</Area>
```

Creates collapsible/expandable form sections.

#### Merger Control (Combined Fields)

```xml
<Merger name="Time Merger" pattern="twoInputControls" labelHandling="Combined" leftRatio="5" rightRatio="5">
  <TimePickerField name="TimeFrom" disabled="true">...</TimePickerField>
  <TimePickerField name="TimeThru" disabled="true">...</TimePickerField>
</Merger>
```

**Purpose:** Combine two related fields with shared label

-   **pattern:** `twoInputControls` (two fields side-by-side)
-   **labelHandling:** `Combined` (single label for both)
-   **leftRatio/rightRatio:** Width distribution (5:5 = 50/50 split)

## Example 3: Editable Form with Events - Visit_RescheduleUI

**Location:** `src/Visit/PR/Visit_Reschedule/Visit_RescheduleUI.userinterface.xml`
**Purpose:** Edit visit date/time with save action

### Complete UI XML

```xml
<UIDescription name="Visit::RescheduleUI" schemaVersion="0.0.0.5">
  <Page pagePattern="SingleSectionDialogPage" onBackDiscard="true">
    <PageHeader>
      <Bindings>
        <Resource target="title" type="Label" id="VisitRescheduleId" defaultLabel="Reschedule" />
      </Bindings>
      <MenuItems>
        <MenuItem directlyVisible="true" itemId="rescheduleVisit">
          <Bindings>
            <Resource target="Text" type="Label" id="rescheduleVisitId" defaultLabel="Done" />
            <Resource target="Icon" type="Image" id="CheckGrey24" defaultImage="light/done_24.png" />
          </Bindings>
          <Events>
            <ButtonPressedEvent event="rescheduleVisit" />
          </Events>
        </MenuItem>
      </MenuItems>
    </PageHeader>
    <Section sectionName="masterSection" sectionPattern="SingleAreaSection">
      <Area areaName="mainArea" areaPattern="GroupedElementsArea">
        <GroupElement name="VisitInfoGroup">
          <Bindings>
            <Resource target="Title" type="Label" id="VisitInformation" defaultLabel=" " />
          </Bindings>

          <!-- Start Date/Time -->
          <Merger name="StartDateMerger" pattern="twoInputControls" labelHandling="Combined" separator="," leftRatio="5" rightRatio="5">
            <DatePickerField name="VisitStartDate">
              <Bindings>
                <Resource target="Label" type="Label" defaultLabel="Visit Start Date/Time" id="VisitStartDate" />
                <Binding target="Value" binding="ProcessContext::RescheduleVisitBo.dateFrom" bindingMode="TWO_WAY" />
              </Bindings>
            </DatePickerField>
            <TimePickerField name="TimeFrom">
              <Bindings>
                <Binding target="Value" binding="ProcessContext::RescheduleVisitBo.timeFrom" bindingMode="TWO_WAY" />
              </Bindings>
            </TimePickerField>
          </Merger>

          <!-- End Date/Time -->
          <Merger name="EndDateMerger" pattern="twoInputControls" labelHandling="Combined" separator="," leftRatio="5" rightRatio="5">
            <DatePickerField name="VisitEndDate">
              <Bindings>
                <Resource target="Label" type="Label" defaultLabel="Visit End Date/Time" id="VisitEndDate" />
                <Binding target="Value" binding="ProcessContext::RescheduleVisitBo.dateThru" bindingMode="TWO_WAY" />
              </Bindings>
            </DatePickerField>
            <TimePickerField name="TimeThru">
              <Bindings>
                <Binding target="Value" binding="ProcessContext::RescheduleVisitBo.timeThru" bindingMode="TWO_WAY" />
              </Bindings>
            </TimePickerField>
          </Merger>

          <!-- Duration (Read-Only) -->
          <InputArea name="Duration" editable="false">
            <Bindings>
              <Resource target="Label" type="Label" defaultLabel="Duration" id="Duration" />
              <Binding target="Value" binding="ProcessContext::RescheduleVisitBo.duration" bindingMode="TWO_WAY" />
            </Bindings>
          </InputArea>
        </GroupElement>
      </Area>
    </Section>
  </Page>
</UIDescription>
```

### Analysis

#### Menu Items (Action Buttons)

```xml
<MenuItem directlyVisible="true" itemId="rescheduleVisit">
  <Events>
    <ButtonPressedEvent event="rescheduleVisit" />
  </Events>
</MenuItem>
```

**Event Flow:**

```
User clicks "Done" button
    |
UI fires ButtonPressedEvent("rescheduleVisit")
    |
Process handles event (defined in Process definition)
    |
Process action executes (e.g., save, validate, navigate)
```

#### TWO_WAY Data Binding

```xml
<Binding target="Value" binding="ProcessContext::RescheduleVisitBo.dateFrom" bindingMode="TWO_WAY" />
```

-   **Read:** UI displays current value from BO
-   **Write:** User edits -> value written back to BO
-   Required for editable fields

#### Editable vs Disabled

-   **editable="false":** Computed/calculated fields (looks editable but cannot be modified)
-   **disabled="true":** Greyed out, clearly read-only

## UI Control Types

### Input Controls

| Control                | Purpose                        | Example Use            |
| ---------------------- | ------------------------------ | ---------------------- |
| **InputArea**          | Single-line text input/display | Name, ID, Status       |
| **InputAreaMultiLine** | Multi-line text input/display  | Notes, Description     |
| **DatePickerField**    | Date selection                 | Visit Date, Due Date   |
| **TimePickerField**    | Time selection                 | Start Time, End Time   |
| **DropdownField**      | Single selection from list     | Status, Type, Category |
| **CheckboxField**      | Boolean toggle                 | Active, Required       |
| **NumericField**       | Number input                   | Quantity, Price        |

### List Controls

| Control         | Purpose                     | Example Use                 |
| --------------- | --------------------------- | --------------------------- |
| **GroupedList** | List of items from LO       | Account Receivables, Visits |
| **SimpleList**  | Basic list without grouping | Options, Choices            |
| **Grid**        | Tabular data display        | Order Items, Products       |

### Container Controls

| Control          | Purpose                        | Example Use                |
| ---------------- | ------------------------------ | -------------------------- |
| **GroupElement** | Grouped form fields with title | Visit Information, Address |
| **Merger**       | Combine related fields         | Date/Time, First/Last Name |
| **TabStrip**     | Tabbed interface               | Order Tabs, Product Tabs   |

### Layout Controls

| Element    | Purpose          | Example Use         |
| ---------- | ---------------- | ------------------- |
| **Col**    | Column container | Grid layout columns |
| **Row**    | Row container    | Grid layout rows    |
| **Spacer** | Empty space      | Visual separation   |

## Binding Patterns

### Pattern 1: Process Variable

```xml
<Binding target="Value" binding="ProcessContext::VariableName" bindingMode="ONE_WAY" />
```

### Pattern 2: BO Property

```xml
<Binding target="Value" binding="ProcessContext::VisitBo.name" bindingMode="TWO_WAY" />
```

### Pattern 3: BO Nested Property

```xml
<Binding target="Value" binding="ProcessContext::VisitBo.status.text" bindingMode="ONE_WAY" />
```

### Pattern 4: LO Item Property (List Context)

```xml
<Binding target="Amount" binding=".amount" bindingMode="ONE_WAY" />
```

### Pattern 5: LO Property (List Level)

```xml
<Binding target="Count" binding="ProcessContext::AccountReceivableList.itemCount" bindingMode="ONE_WAY" />
```

### Pattern 6: Object Property Path

```xml
<Binding target="Value" binding="ProcessContext::RetailStoreAddress.zipCodeAndCity" bindingMode="ONE_WAY" />
```

## Binding Modes

| Mode         | Direction | Use Case              |
| ------------ | --------- | --------------------- |
| **ONE_TIME** | Read once | Static labels, titles |
| **ONE_WAY**  | BO -> UI  | Read-only displays    |
| **TWO_WAY**  | BO <-> UI | Editable fields       |

## Format Patterns

### Decimal Formatting

```xml
<Binding target="Amount" type="Decimal" binding=".amount" formatV2="10.2" bindingMode="ONE_WAY" />
```

**formatV2="10.2":** 10 total digits, 2 decimal places. Example: 1234.56

### Date Formatting

```xml
<Binding target="Value" type="Date" binding=".receiptDate" format="shortDate" bindingMode="ONE_WAY" />
```

**format options:**

-   `shortDate` - MM/DD/YYYY
-   `longDate` - Month DD, YYYY
-   `dateTime` - MM/DD/YYYY HH:MM

### Currency Formatting

```xml
<Binding target="Value" type="Currency" binding=".totalAmount" formatV2="10.2" bindingMode="ONE_WAY" />
```

Framework adds currency symbol based on locale.

## Responsive Layout Strategy

### Layout Hierarchy

```
<ItemListLayout>
  <Default>         <!-- Desktop/Browser -->
  <Tablet>          <!-- Tablet devices -->
  <Phone>           <!-- Mobile phones -->
</ItemListLayout>
```

### Design Principles

**Desktop (Default):**

-   Horizontal layout
-   Multiple columns visible
-   Fixed widths in `em`
-   More information density

**Tablet:**

-   Moderate horizontal layout
-   Some columns combined
-   Mix of fixed and flexible widths

**Phone:**

-   Vertical/stacked layout
-   Minimal columns (1-2)
-   Flexible widths (`flex`)
-   Essential information only

## Event Handling

### UI Events

**Common Events:**

-   `ButtonPressedEvent` - Button/menu item clicked
-   `ItemSelectedEvent` - List item selected
-   `ValueChangedEvent` - Field value changed
-   `SwipeEvent` - Swipe gesture
-   `LongPressEvent` - Long press on item

### Event Definition (UI)

```xml
<Events>
  <ButtonPressedEvent event="rescheduleVisit" />
</Events>
```

### Event Handler (Process)

```xml
<Action actionType="VIEW" name="ShowView">
  <UIDescription>Visit::RescheduleUI</UIDescription>
  <Events>
    <Event name="rescheduleVisit" action="HandleReschedule" />
  </Events>
</Action>

<Action name="HandleReschedule" actionType="LOGIC" call="ProcessContext::VisitBo.reschedule">
  <Parameters>
    <Input name="newDateFrom" value="ProcessContext::RescheduleVisitBo.dateFrom" />
    <Input name="newTimeFrom" value="ProcessContext::RescheduleVisitBo.timeFrom" />
  </Parameters>
  <TransitionTo action="SaveAndClose" />
</Action>
```

## Best Practices

### 1. Use Appropriate Binding Modes

```xml
<!-- Read-only display -->
<Binding binding="ProcessContext::VisitBo.name" bindingMode="ONE_WAY" />

<!-- Editable field -->
<Binding binding="ProcessContext::VisitBo.name" bindingMode="TWO_WAY" />
```

### 2. Provide Responsive Layouts

Always define Phone, Tablet, and Default layouts for lists:

```xml
<ItemListLayout>
  <Default><!-- Desktop layout --></Default>
  <Tablet><!-- Tablet layout --></Tablet>
  <Phone><!-- Phone layout --></Phone>
</ItemListLayout>
```

### 3. Use Meaningful Layout Types

```xml
<!-- Good: Semantic styling -->
<Row layoutType="itemIdentifier" bindingId="Name" />
<Row layoutType="itemValue" bindingId="Amount" />
```

### 4. Localize All Text

```xml
<!-- Good: Localized with ID -->
<Resource target="Label" type="Label" id="AmountLabelId" defaultLabel="Amount" />
```

### 5. Group Related Fields

```xml
<GroupElement name="Address">
  <InputArea name="Street" />
  <InputArea name="City" />
  <InputArea name="PostalCode" />
</GroupElement>
```

### 6. Use Mergers for Related Pairs

```xml
<Merger pattern="twoInputControls" labelHandling="Combined">
  <DatePickerField name="StartDate" />
  <TimePickerField name="StartTime" />
</Merger>
```

## Key Takeaways

1. **UI binds to ProcessContext** variables (BOs, LOs, simple types)
2. **Responsive layouts** adapt to device (Phone, Tablet, Default)
3. **Binding modes** control data flow (ONE_TIME, ONE_WAY, TWO_WAY)
4. **Col/Row grid system** structures item layouts
5. **GroupElement** organizes form fields into sections
6. **MenuItems** define action buttons in header
7. **Events** connect UI interactions to Process actions
8. **Resource bindings** provide localized labels
9. **Format patterns** control display (dates, decimals, currency)
10. **Control types** match data types (InputArea, DatePicker, GroupedList)

## Files Referenced

| File Path                                                                       | Purpose                           |
| ------------------------------------------------------------------------------- | --------------------------------- |
| src/Call/PR/Call_AccountReceivables/Call_AccountReceivablesUI.userinterface.xml | List view with responsive layouts |
| src/Visit/PR/Visit_Info/Visit_InfoUI.userinterface.xml                          | Form view with grouped elements   |
| src/Visit/PR/Visit_Reschedule/Visit_RescheduleUI.userinterface.xml              | Editable form with events         |

---

_This documentation is maintained by the Modeler CLI plugin and refreshed on workspace upgrade._
