- Added dependency for @microsoft/power-apps to package.json. - Updated power.config.json to include appId, environmentId, and connection references. - Implemented sanitisation function for HTML content in App.tsx to prevent XSS. - Enhanced error handling in email loading and marking as read functionalities. - Updated email display logic to handle HTML content and previews. - Refactored OutlookService to use auto-generated service from @microsoft/power-apps. - Added new methods for sending, marking as read, and deleting emails in OutlookService. - Updated types for Email to include bodyPreview, isHtml, hasAttachments, and importance. - Configured Vite to exclude @microsoft/power-apps/data from the build. - Created .gitignore to exclude build artifacts and environment files. - Added local development shim for @microsoft/power-apps/data to support local testing. - Defined type stubs for @microsoft/power-apps/data to facilitate local development.
297 lines
10 KiB
Markdown
297 lines
10 KiB
Markdown
# 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
|