# Power Apps Code Apps — Part 2: Connectors & Outlook

> Full email client in a code app, built with React + Fluent UI v9, powered by the Outlook connector.

This is the companion repo for [Part 2 of the blog series](https://www.thatsagoodquestion.info/power-apps-code-apps). Make sure you have completed Part 1 before continuing.

---

## What you will build

An Outlook-like email client with:

- **Folder navigation** — Inbox, Sent, Drafts, Trash
- **Email list** — unread indicators, avatar colors, relative timestamps
- **Reading pane** — full email body (HTML-safe) with Reply / Forward / Delete
- **Compose dialog** — Fluent UI v9 dialog with validation
- **Connections panel** — visual reference of connectors + PAC CLI commands
- **Real-time search** — filter by sender or subject

All built with **Fluent UI v9** (`@fluentui/react-components`) and the **Outlook connector**.

---

## Prerequisites

| Requirement | Version |
|---|---|
| **Node.js** | 18+ |
| **npm** | 9+ |
| **PAC CLI** | 2.6+ (`dotnet tool install -g Microsoft.PowerApps.CLI`) |
| **Power Apps environment** | Licensed user with code apps enabled |
| **Microsoft 365 account** | For the Outlook connector |

---

## Quick start

```bash
# 1. Clone & install
git clone <this-repo>
cd power-apps-codeapps-blog-part2
npm install

# 2. Run locally (UI only, no connector data)
npm run dev

# 3. Run locally WITH real connector data
#    Terminal 1:
npm run dev
#    Terminal 2:
pac code run -a http://localhost:5173

# 4. Open the URL printed by pac code run in your browser
```

---

## Project structure

```
power-apps-codeapps-blog-part2/
├── index.html               HTML shell
├── package.json              Dependencies & scripts
├── tsconfig.json             TypeScript config
├── vite.config.ts            Vite dev server & build config
├── power.config.json         Power Platform app manifest (required by PAC CLI)
├── .gitignore                Excludes dist/, .power/, node_modules/
└── src/
    ├── main.tsx              Entry point — FluentProvider + light/dark theme
    ├── App.tsx               Main UI: nav rail, folders, email list, reading pane
    ├── index.css             Minimal reset (Fluent UI handles component styles)
    ├── shims/
    │   └── power-apps-data.ts  Local dev shim for @microsoft/power-apps/data
    ├── types/
    │   ├── index.ts          Shared types (Email, Folder, FOLDER_PATH_MAP)
    │   └── power-apps.d.ts   Type declarations for the Power Platform runtime
    ├── services/
    │   └── OutlookService.ts Adapter wrapping the generated Outlook_comService
    └── generated/            Auto-generated by pac code add-data-source
        ├── index.ts
        ├── models/
        │   └── Outlook_comModel.ts   Typed request/response interfaces
        └── services/
            └── Outlook_comService.ts All connector operations as static methods
```

---

## Architecture

```
┌──────────────────────────────────────────────────────┐
│                    Your Code App                      │
│                                                       │
│   React + Fluent UI  →  OutlookService  →  Generated  │
│                          (adapter)         Service     │
│                                              ↕        │
│              ┌───────────────────────────────────┐    │
│              │    Power Platform Runtime          │    │
│              │  ─────────────────────────────     │    │
│              │  @microsoft/power-apps/data        │    │
│              │  → Outlook connector API           │    │
│              └───────────────────────────────────┘    │
└──────────────────────────────────────────────────────┘
```

`src/services/OutlookService.ts` wraps the auto-generated `Outlook_comService` and maps its responses to the UI`s `Email` type. All real connector calls go through the Power Platform runtime SDK.

---

## Setting up your own connections

### 1. Check your connections

```bash
pac connection list
```

Example output:

```
Connected as user@contoso.com
Id                               Name        API Id                                              Status
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Outlook.com /providers/Microsoft.PowerApps/apis/shared_outlook  Connected
```

### 2. Add the connector to your code app

```bash
pac code add-data-source \
  -a shared_outlook \
  -c <your-connection-id>
```

This auto-generates typed files in `src/generated/`:

```
src/generated/
  ├── models/Outlook_comModel.ts     ← request/response types
  └── services/Outlook_comService.ts ← typed service with all operations
```

### 3. Update `power.config.json`

Replace the placeholder values with your real IDs:

```json
{
  "environmentId": "<your-environment-id>",
  "connectionReferences": {
    "<your-connection-reference-id>": {
      "id": "/providers/Microsoft.PowerApps/apis/shared_outlook",
      ...
    }
  }
}
```

### 4. Run with real connections

```bash
# Terminal 1 — Vite dev server
npm run dev

# Terminal 2 — Power Platform connection proxy
pac code run -a http://localhost:5173
```

Open the URL printed by `pac code run` in your browser.

---

## Removing an unused data source / connection

If you added a connection by mistake, or the schema changed and you need to refresh:

### Delete the data source

```bash
pac code delete-data-source -a <apiName> -ds <dataSourceName>
```

For example, to remove an Outlook data source named `outlook`:

```bash
pac code delete-data-source -a shared_outlook -ds outlook
```

This removes:
- The entry from `power.config.json` → `connectionReferences`
- The generated files under `src/generated/`

### Clean up manually (if needed)

If the CLI does not fully clean up:

1. **`power.config.json`** — Remove the connection reference entry from `connectionReferences`
2. **`src/generated/`** — Delete the corresponding `*Model.ts` and `*Service.ts` files
3. **`.power/schemas/`** — Delete the connector schema folder (e.g., `.power/schemas/outlook/`)
4. **`src/services/OutlookService.ts`** — Remove or update the adapter that imports from the deleted generated service

### Verify

```bash
npx tsc --noEmit   # should compile without errors
npm run build       # should produce a clean build
```

> **Important**: There is no `refresh` command yet. If a connector schema changes, delete the data source and re-add it.

---

## Available connector methods

After running `pac code add-data-source`, the generated `Outlook_comService.ts` exposes these static methods:

| Method | Description |
|---|---|
| `GetEmails(folderPath, ...)` | Get emails from a folder |
| `GetEmailsV2(folderPath, ...)` | V2 with more filter options |
| `GetEmail(messageId)` | Get a single email by ID |
| `SendEmail(message)` | Send email (plain text) |
| `SendEmailV2(message)` | Send email (HTML) |
| `MarkAsRead(messageId)` | Mark as read |
| `DeleteEmail(messageId)` | Delete email |
| `Move(messageId, folderPath)` | Move to another folder |
| `Flag(messageId)` | Flag an email |
| `ReplyTo / ReplyToV2 / ReplyToV3` | Reply (text/HTML) |
| `ForwardEmail(messageId, body)` | Forward |

All methods return `Promise<IOperationResult<T>>` — access the data via `result.data`.

---

## Connection references

Code apps use **connection references** instead of binding to user-specific connections:

| Benefit | Description |
|---|---|
| **Environment promotion** | Connections change per env (dev/staging/prod) without code changes |
| **Managed identity** | System-assigned identities instead of user credentials |
| **Governance** | IT audits via DLP policies |

---

## Deploy to Power Platform

```bash
# Build and push to your environment
npm run build
pac code push
```

To target a specific solution:

```bash
pac code push --solution <solution-id>
```

---

## NPM scripts

| Script | Description |
|---|---|
| `npm run dev` | Start Vite dev server at `http://localhost:5173` |
| `npm run build` | Type-check + production build |
| `npm run preview` | Preview the production build locally |

---

## Key differences from Canvas Apps

| Aspect | Canvas Apps | Code Apps |
|---|---|---|
| **UI Framework** | Power Fx formula bar | React / Vue / Svelte |
| **Connector access** | Built-in connector picker | PAC CLI + typed client library |
| **Data model** | Implicit, delegation-based | Explicit TypeScript types |
| **Styling** | Themed controls | Fluent UI / any CSS framework |
| **Deployment** | Packaged by Power Platform | `pac code push` |
| **Source control** | Limited | Full git-native workflow |

---

## References

- [How to: Connect your code app to data](https://learn.microsoft.com/en-us/power-apps/developer/code-apps/how-to/connect-to-data) — Microsoft Learn
- [Power Apps code apps overview](https://learn.microsoft.com/en-us/power-apps/developer/code-apps/overview) — Microsoft Learn
- [Code apps architecture](https://learn.microsoft.com/en-us/power-apps/developer/code-apps/architecture) — Microsoft Learn
- [pac code add-data-source](https://learn.microsoft.com/en-us/power-platform/developer/cli/reference/code#pac-code-add-data-source) — PAC CLI reference
- [pac code delete-data-source](https://learn.microsoft.com/en-us/power-platform/developer/cli/reference/code#pac-code-delete-data-source) — PAC CLI reference
- [pac connection list](https://learn.microsoft.com/en-us/power-platform/developer/cli/reference/connection#pac-connection-list) — PAC CLI reference
- [Connector classification (DLP)](https://learn.microsoft.com/en-us/power-platform/admin/dlp-connector-classification) — Microsoft Learn
- [Fluent UI v9 — React components](https://react.fluentui.dev/) — Microsoft
- [Part 1: Power Apps code apps tutorial](https://www.thatsagoodquestion.info/power-apps-code-apps) — That's a good question
