# Cockpit Card Implementation Checklist

## Overview

Adding a new card to the Customer 360 Cockpit (Call_Customer360TabUI) requires changes in **exactly 7 locations**. Missing any of these will cause the card to not appear, not load data, or display incorrectly.

---

## The 7 Required Locations

### 1. Process Declarations

**File:** `src/Call/PR/Call_StoreCockpitTab/Call_StoreCockpitTabProcess.processflow.xml`

**Section:** `<Entry><ProcessContext><Declarations>`

Add 4 declarations for each card:

```xml
<!-- Card: MyNewCard -->
<Declaration name="CardMyNewCard_List" type="LoMyNewCardForStoreCockpit" />
<Declaration name="CardMyNewCard_InformationText" type="String" />
<Declaration name="CardMyNewCard_DataLoaded" type="DomBool" />
<Declaration name="CardMyNewCard_DisplayedSubcomponentName" type="String" />
```

**Pattern:**

-   `CardXxx_List` - The list object containing data
-   `CardXxx_InformationText` - Info text (e.g., "3 / 10")
-   `CardXxx_DataLoaded` - Boolean flag for loading state
-   `CardXxx_DisplayedSubcomponentName` - **MANDATORY** for proper display

---

### 2. EntryActions CREATE

**File:** `src/Call/PR/Call_StoreCockpitTab/Call_StoreCockpitTabProcess.processflow.xml`

**Section:** `<Entry><EntryActions>`

Create the list object instance:

```xml
<!-- Card: MyNewCard -->
<Action actionType="CREATE" name="CardMyNewCard_GetList" type="LoMyNewCardForStoreCockpit">
  <Return name="ProcessContext::CardMyNewCard_List" />
</Action>
```

---

### 3. ShowCockpit Events

**File:** `src/Call/PR/Call_StoreCockpitTab/Call_StoreCockpitTabProcess.processflow.xml`

**Section:** `<Body><Actions>` - Find the VIEW action named "ShowCockpit"

Add event handler for card actions:

```xml
<Action actionType="VIEW" name="ShowCockpit">
  <UIDescription>Call::Customer360TabUI</UIDescription>
  <Events>
    <!-- ... existing events ... -->
    <Event name="cardMyNewCard_linkBarButtonPressed" action="CardMyNewCard_LoadData" />
    <Event name="cardMyNewCard_itemSelected" action="CardMyNewCard_ItemSelected" />
  </Events>
</Action>
```

---

### 4. Load Chain Actions

**File:** `src/Call/PR/Call_StoreCockpitTab/Call_StoreCockpitTabProcess.processflow.xml`

**Section:** `<Body><Actions>`

Add load action chain (typically 4 actions):

```xml
<!-- Load Data -->
<Action name="CardMyNewCard_LoadData" actionType="LOGIC"
        call="ProcessContext::CardMyNewCard_List.getAllItemsForCard">
  <Parameters>
    <Input name="numberOfListItems" type="Literal" value="5" />
    <Input name="currentCustomerPKey" value="ProcessContext::CurrentCustomerPKey" />
  </Parameters>
  <TransitionTo action="CardMyNewCard_GetInfo" />
</Action>

<!-- Get Info Text -->
<Action name="CardMyNewCard_GetInfo" actionType="LOGIC"
        call="ProcessContext::CardMyNewCard_List.getInfoForCard">
  <Return name="ProcessContext::CardMyNewCard_InformationText" />
  <TransitionTo action="AssignDisplayedSubcomponentNameForMyNewCard" />
</Action>

<!-- Assign DisplayedSubcomponentName (MANDATORY) -->
<Action name="AssignDisplayedSubcomponentNameForMyNewCard" actionType="LOGIC"
        call="ProcessContext::CardController.getDisplayedSubcomponentName">
  <Parameters>
    <Input name="loItems" value="ProcessContext::CardMyNewCard_List" />
    <Input name="type" type="Literal" value="CockpitList" />
  </Parameters>
  <Return name="ProcessContext::CardMyNewCard_DisplayedSubcomponentName" />
  <TransitionTo action="CardMyNewCard_SetDataLoaded" />
</Action>

<!-- Set DataLoaded Flag -->
<Action name="CardMyNewCard_SetDataLoaded" actionType="LOGIC" call="Utils.identity">
  <Parameters>
    <Input name="value" type="Literal" value="1" />
  </Parameters>
  <Return name="ProcessContext::CardMyNewCard_DataLoaded" />
</Action>

<!-- Item Selected Handler -->
<Action name="CardMyNewCard_ItemSelected" actionType="PROCESS"
        process="MyModule::OverviewProcess">
  <Parameters>
    <Input name="ItemList" value="ProcessContext::CardMyNewCard_List" />
    <Input name="selectedItemPKey" value="Event.itemPKey" />
  </Parameters>
</Action>
```

---

### 5. UI CardContainer

**File:** `src/Call/PR/Call_StoreCockpitTab/Call_Customer360TabUI.userinterface.xml`

**Section:** Find the `<Group>` containing other cards, add new CardContainer:

```xml
<CardContainer cardName="cardMyNewCard" dataLoadedBinding="ProcessContext::CardMyNewCard_DataLoaded">
  <CardHeader>
    <Bindings>
      <Resource target="title" type="Label" id="MyNewCardId" defaultLabel="My New Card" />
      <Binding target="infoText" type="Text"
               binding="ProcessContext::CardMyNewCard_InformationText"
               bindingMode="ONE_WAY" />
    </Bindings>
    <LinkBar>
      <LinkBarItem id="showAll" itemType="button">
        <Event name="pressed" />
        <Bindings>
          <Resource target="caption" type="Label" id="ShowAllId" defaultLabel="Show All" />
        </Bindings>
      </LinkBarItem>
    </LinkBar>
  </CardHeader>
  <CockpitList listId="cardMyNewCard_list"
               itemLayout="MyNewCardForStoreCockpitPattern"
               dataSource="ProcessContext::CardMyNewCard_List">
    <Event name="itemSelected" />
    <Bindings>
      <Resource target="noDataMessage" type="Label"
                id="NoMyNewCardId"
                defaultLabel="No items found" />
      <Binding target="DisplayedSubcomponentName" type="Text"
               binding="ProcessContext::CardMyNewCard_DisplayedSubcomponentName"
               bindingMode="ONE_WAY" />
    </Bindings>
  </CockpitList>
</CardContainer>
```

**Critical:** The `DisplayedSubcomponentName` binding is **MANDATORY**. Without it, CockpitList always shows NoDataMessage even when data exists.

---

### 6. Card Visibility Allowlist

**File:** `src/Utilities/BO/BoStoreCockpitHelper/Mv2/BoStoreCockpitHelper.IsCardVisible.bl.js`

Add card name to the allowlist:

```javascript
var allowedCards = [
    'cardHeader',
    'cardSellIns',
    'cardActivities',
    // ... existing cards ...
    'cardMyNewCard', // ADD THIS LINE
    'cardLastVisitSummary',
];
```

---

### 7. Locale Labels

**File:** `src/Locale/en.locale.xml`

Add labels:

```xml
<!-- Card Title -->
<LocalizationString name="MyNewCardId" defaultLabel="My New Card" />

<!-- No Data Message -->
<LocalizationString name="NoMyNewCardId" defaultLabel="No items found" />

<!-- LinkBar Button -->
<LocalizationString name="ShowAllId" defaultLabel="Show All" />
```

---

## DisplayedSubcomponentName Deep Dive

### Why It's Mandatory

The `DisplayedSubcomponentName` controls which subcomponent of CockpitList is shown:

-   When list has data -> shows the list
-   When list is empty -> shows NoDataMessage

**Without this binding:** CockpitList cannot determine what to display and defaults to NoDataMessage, even when the list contains items.

### The Three Required Pieces

1. **Process Declaration:**

```xml
<Declaration name="CardXxx_DisplayedSubcomponentName" type="String" />
```

2. **Process Action:**

```xml
<Action name="AssignDisplayedSubcomponentNameForXxx" actionType="LOGIC"
        call="ProcessContext::CardController.getDisplayedSubcomponentName">
  <Parameters>
    <Input name="loItems" value="ProcessContext::CardXxx_List" />
    <Input name="type" type="Literal" value="CockpitList" />
  </Parameters>
  <Return name="ProcessContext::CardXxx_DisplayedSubcomponentName" />
</Action>
```

3. **UI Binding:**

```xml
<Binding target="DisplayedSubcomponentName" type="Text"
         binding="ProcessContext::CardXxx_DisplayedSubcomponentName"
         bindingMode="ONE_WAY" />
```

---

## Common Mistakes

| Mistake                              | Symptom                                          | Fix                                                           |
| ------------------------------------ | ------------------------------------------------ | ------------------------------------------------------------- |
| Forgetting DisplayedSubcomponentName | Card shows "No data" even when data is loaded    | Add all 3 pieces (declaration, action, binding)               |
| Wrong Event Name                     | Nothing happens when clicking card items/buttons | Event name in UI must match Event name in Process             |
| Missing from Visibility Allowlist    | Card doesn't appear at all                       | Add card name to `BoStoreCockpitHelper.IsCardVisible.bl.js`   |
| Incorrect Naming Convention          | Bindings fail, data doesn't load                 | Use consistent naming: `CardXxx_` prefix for all declarations |
| Missing Locale Labels                | Card shows label IDs instead of text             | Add all labels to locale files                                |

---

## Testing Checklist

After adding a new card:

-   [ ] Card appears in the cockpit
-   [ ] Card title displays correctly (not label ID)
-   [ ] Data loads when card is opened
-   [ ] Info text shows correct count (e.g., "3 / 10")
-   [ ] List items display when data exists
-   [ ] NoDataMessage shows when list is empty
-   [ ] Clicking list items navigates correctly
-   [ ] "Show All" button works (if applicable)
-   [ ] Card respects visibility rules from BoStoreCockpitHelper

---

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