@khester/create-dynamics-app 2.8.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/artifacts/registry.d.ts.map +1 -1
- package/dist/artifacts/registry.js +24 -10
- package/dist/artifacts/registry.js.map +1 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/teams-app/README.md +1 -0
- package/templates/teams-app/_variants/tab.meeting/appPackage/manifest.template.json +46 -0
- package/templates/teams-app/_variants/tab.meeting/auth.html +15 -0
- package/templates/teams-app/_variants/tab.meeting/env.local.template +3 -0
- package/templates/teams-app/_variants/tab.meeting/src/App.tsx +59 -0
- package/templates/teams-app/_variants/tab.meeting/src/auth-bridge.ts +52 -0
- package/templates/teams-app/_variants/tab.meeting/src/components/SidePanel.tsx +124 -0
- package/templates/teams-app/_variants/tab.meeting/src/components/StageView.tsx +93 -0
- package/templates/teams-app/_variants/tab.meeting/src/hooks/useHashRoute.ts +16 -0
- package/templates/teams-app/_variants/tab.meeting/src/hooks/useTeamsAuth.ts +121 -0
- package/templates/teams-app/_variants/tab.meeting/src/pages/Config.tsx +60 -0
- package/templates/teams-app/_variants/tab.meeting/src/pages/Remove.tsx +9 -0
- package/templates/teams-app/_variants/tab.meeting/src/vite-env.d.ts +10 -0
- package/templates/teams-app/_variants/tab.meeting/vite.config.ts +19 -0
- package/templates/teams-bot/.env.example +2 -1
- package/templates/teams-bot/README.md +14 -6
- package/templates/teams-bot/_variants/bot.message-extension/appPackage/manifest.template.json +56 -0
- package/templates/teams-bot/_variants/bot.message-extension/src/bot/MessageExtensionBot.ts +114 -0
- package/templates/teams-bot/_variants/bot.message-extension/src/index.ts +51 -0
- package/templates/teams-bot/_variants/bot.message-extension/src/mock/mockData.ts +30 -0
package/README.md
CHANGED
|
@@ -48,8 +48,8 @@ npm run metadata:pull -- --entities account,contact # live metadata → typed s
|
|
|
48
48
|
| `web-resource` | React web resource (webpack bundle) | **v8 or v9** |
|
|
49
49
|
| `dialog-form` | Single React form host (opened as a dialog) | **v8 or v9** |
|
|
50
50
|
| `static-web-app` | Azure SWA — React frontend + Functions `api/` | **v8 or v9** |
|
|
51
|
-
| `teams-app` | Teams tab (React + teams-js), optional Graph (`--graph`) | v9 |
|
|
52
|
-
| `teams-bot` | Teams bot (Bot Framework SDK v4 + Express, mock mode) — echo
|
|
51
|
+
| `teams-app` | Teams tab (React + teams-js) — basic, SSO, dashboard, or in-meeting side panel/stage (`--tab-kind`), optional Graph (`--graph`) | v9 |
|
|
52
|
+
| `teams-bot` | Teams bot / message extension (Bot Framework SDK v4 + Express, mock mode) — echo, proactive notifications, or compose-box search/action/link (`--bot-kind`) | — |
|
|
53
53
|
|
|
54
54
|
Run with no flags for an interactive picker.
|
|
55
55
|
|
|
@@ -79,8 +79,8 @@ your `src/Component.tsx` across.
|
|
|
79
79
|
- `--host <custom-page|pcf|web-resource>` — host target for the `host-swap` artifact (default `custom-page`).
|
|
80
80
|
- `--surface <form|panel|dashboard|master-detail>` — surface for the `starter-page` artifact.
|
|
81
81
|
- `--graph` — include Microsoft Graph (teams-app).
|
|
82
|
-
- `--tab-kind <basic|sso|dashboard>` — tab kind for the `teams-app` artifact (default `basic`).
|
|
83
|
-
- `--bot-kind <echo|notification>` — bot kind for the `teams-bot` artifact (default `echo`).
|
|
82
|
+
- `--tab-kind <basic|sso|dashboard|meeting>` — tab kind for the `teams-app` artifact (default `basic`). `meeting` is an in-meeting app (side panel + shared stage via `shareAppContentToStage`).
|
|
83
|
+
- `--bot-kind <echo|notification|message-extension>` — bot kind for the `teams-bot` artifact (default `echo`). `message-extension` is a Bot-Framework-backed compose-box search / action / link-unfurling extension.
|
|
84
84
|
- `--with-components` — install [`@khester/reusable-components`](https://www.npmjs.com/package/@khester/reusable-components) (a curated Fluent **v8** React set: `ReusableCard`, `CustomSection`, `FileUploadField`, `SearchComponent`, `DetailsListComponent`, the localhost-gated `logger`, …) plus its `@fluentui/react` v8 peer. Opt-in for the v8 React hosts that don't already bundle it — `power-pages`, `web-resource`, `dialog-form` (`react-custom-page`, `grid-starter`, and `host-swap` ship it as a base dependency already); warned-and-ignored elsewhere; **errors** if combined with `--v9`.
|
|
85
85
|
- `--from-design <file>` — generate from a form-builder export (a `FormBuilderProject` JSON, e.g. from `/generate-form`). Wraps `@dataverse-kit/export-engine` to produce a deployable project (host + form code + a design-derived data layer). Supported targets: `web-resource`, `pcf`, `static-web-app`. From-design output is generated by the export engine and is structurally different from a blank starter (it ships its own token tooling); `package.json.dynamicsKit.artifact` records which.
|
|
86
86
|
- `--skip-git`, `--skip-install`.
|
|
@@ -95,7 +95,7 @@ See `CHANGELOG.md`. In short: removed the consulting flags (`-c/-e/-p/-d/--gener
|
|
|
95
95
|
|
|
96
96
|
## Testing & coverage boundaries
|
|
97
97
|
|
|
98
|
-
- Unit + smoke tests (`npm test`) run the scaffold pipeline for all
|
|
98
|
+
- Unit + smoke tests (`npm test`) run the scaffold pipeline for all 13 artifacts (zero-residual-token + variant/prune checks) but do **not** `npm install` or build the generated projects, except the build gates below.
|
|
99
99
|
- Build gates (`npm run test:e2e`) scaffold + `npm install` + build the React custom-page templates (Vite), the PCF templates (`pcf-scripts`), and **all three `host-swap` hosts** (custom-page → Vite, pcf → pcf-scripts, web-resource → webpack) — the host-swap gates prove one `Component.tsx` builds under every host toolchain.
|
|
100
100
|
- React artifacts are verified to `tsc --noEmit` clean for v8 and v9 via manual installs; **PCF** type-correctness (against generated `ManifestTypes` from `pcf-scripts refreshTypes`) is verified manually, not in CI.
|
|
101
101
|
- The `--from-design` generated-project build is verified manually.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/artifacts/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAGlB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAoJpB;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/artifacts/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAGlB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAoJpB;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,kBAAkB,EAkezC,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEtE;AAED,wBAAgB,kBAAkB,IAAI,kBAAkB,EAAE,CAEzD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAI1E,CAAC"}
|
|
@@ -449,10 +449,11 @@ export const ARTIFACTS = [
|
|
|
449
449
|
},
|
|
450
450
|
{
|
|
451
451
|
id: 'teams-app',
|
|
452
|
-
label: '💬 Teams App — Teams tab (React, Fluent v9, basic/SSO/dashboard, optional Graph)',
|
|
452
|
+
label: '💬 Teams App — Teams tab (React, Fluent v9, basic/SSO/dashboard/meeting, optional Graph)',
|
|
453
453
|
description: 'Microsoft Teams tab: React + Fluent v9 + teams-js. Tab kinds: basic (personal tab), ' +
|
|
454
454
|
'sso (Teams SSO + MSAL fallback via an auth.html bridge), dashboard (configurable widget ' +
|
|
455
|
-
'dashboard, SSO-capable)
|
|
455
|
+
'dashboard, SSO-capable), meeting (in-meeting side panel + shared stage, SSO-capable). ' +
|
|
456
|
+
'Optional Graph integration.',
|
|
456
457
|
templateDir: 'teams-app',
|
|
457
458
|
supportsLibraryChoice: false,
|
|
458
459
|
devTools: ['token', 'serve'],
|
|
@@ -466,11 +467,12 @@ export const ARTIFACTS = [
|
|
|
466
467
|
{ name: 'Basic — personal tab, no auth', value: 'basic' },
|
|
467
468
|
{ name: 'SSO — Teams single sign-on with MSAL browser fallback', value: 'sso' },
|
|
468
469
|
{ name: 'Dashboard — configurable widget dashboard (channel + personal, SSO-capable)', value: 'dashboard' },
|
|
470
|
+
{ name: 'Meeting — in-meeting side panel + shared stage (SSO-capable)', value: 'meeting' },
|
|
469
471
|
],
|
|
470
472
|
// A --tab-kind flag would bypass the interactive choices check, so validate here too.
|
|
471
|
-
validate: (v) => v === 'basic' || v === 'sso' || v === 'dashboard'
|
|
473
|
+
validate: (v) => v === 'basic' || v === 'sso' || v === 'dashboard' || v === 'meeting'
|
|
472
474
|
? true
|
|
473
|
-
: `Unknown tab kind ${JSON.stringify(v)}. One of: basic, sso, dashboard.`,
|
|
475
|
+
: `Unknown tab kind ${JSON.stringify(v)}. One of: basic, sso, dashboard, meeting.`,
|
|
474
476
|
},
|
|
475
477
|
{
|
|
476
478
|
name: 'graph',
|
|
@@ -494,6 +496,7 @@ export const ARTIFACTS = [
|
|
|
494
496
|
basic: '_variants/tab.basic',
|
|
495
497
|
sso: '_variants/tab.sso',
|
|
496
498
|
dashboard: '_variants/tab.dashboard',
|
|
499
|
+
meeting: '_variants/tab.meeting',
|
|
497
500
|
},
|
|
498
501
|
to: '.',
|
|
499
502
|
},
|
|
@@ -512,19 +515,26 @@ export const ARTIFACTS = [
|
|
|
512
515
|
},
|
|
513
516
|
// The auth-capable kinds ship useTeamsAuth + the auth.html MSAL bridge.
|
|
514
517
|
{
|
|
515
|
-
when: (vars) => vars.tabKind === 'sso' || vars.tabKind === 'dashboard',
|
|
518
|
+
when: (vars) => vars.tabKind === 'sso' || vars.tabKind === 'dashboard' || vars.tabKind === 'meeting',
|
|
516
519
|
dependencies: { '@azure/msal-browser': '^5.17.0' },
|
|
517
520
|
},
|
|
521
|
+
// The meeting kind's SidePanel/StageView use Fluent icons; the base template
|
|
522
|
+
// does not carry @fluentui/react-icons, so add it only for that kind.
|
|
523
|
+
{
|
|
524
|
+
when: (vars) => vars.tabKind === 'meeting',
|
|
525
|
+
dependencies: { '@fluentui/react-icons': '^2.0.245' },
|
|
526
|
+
},
|
|
518
527
|
],
|
|
519
528
|
templateVersion: '3.0.0',
|
|
520
529
|
available: true,
|
|
521
530
|
},
|
|
522
531
|
{
|
|
523
532
|
id: 'teams-bot',
|
|
524
|
-
label: '🤖 Teams Bot — Bot Framework bot (echo
|
|
533
|
+
label: '🤖 Teams Bot — Bot Framework bot / message extension (echo, notification, message-extension)',
|
|
525
534
|
description: 'Microsoft Teams bot: Bot Framework SDK v4 + Express + TypeScript, with a no-Azure mock ' +
|
|
526
535
|
'mode. Bot kinds: echo (commands + welcome card), notification (proactive messaging via ' +
|
|
527
|
-
'an auth-gated POST /api/notify with a persistent conversation store)
|
|
536
|
+
'an auth-gated POST /api/notify with a persistent conversation store), message-extension ' +
|
|
537
|
+
'(compose-box search + action task module + link unfurling).',
|
|
528
538
|
templateDir: 'teams-bot',
|
|
529
539
|
supportsLibraryChoice: false,
|
|
530
540
|
// token/serve are Dataverse/tab helpers — not applicable to a Node bot server.
|
|
@@ -532,17 +542,20 @@ export const ARTIFACTS = [
|
|
|
532
542
|
prompts: [
|
|
533
543
|
{
|
|
534
544
|
name: 'botKind',
|
|
535
|
-
message
|
|
545
|
+
// A message extension is Bot-Framework-backed too (shares the /api/messages endpoint +
|
|
546
|
+
// Azure Bot registration), so it lives here as a third kind rather than a sibling artifact.
|
|
547
|
+
message: 'Which bot kind? (chat bot or message extension)',
|
|
536
548
|
type: 'list',
|
|
537
549
|
default: 'echo',
|
|
538
550
|
choices: [
|
|
539
551
|
{ name: 'Echo — commands, welcome card, message echo', value: 'echo' },
|
|
540
552
|
{ name: 'Notification — proactive messages via POST /api/notify', value: 'notification' },
|
|
553
|
+
{ name: 'Message Extension — compose-box search / action / link-unfurling', value: 'message-extension' },
|
|
541
554
|
],
|
|
542
555
|
// A --bot-kind flag would bypass the interactive choices check, so validate here too.
|
|
543
|
-
validate: (v) => v === 'echo' || v === 'notification'
|
|
556
|
+
validate: (v) => v === 'echo' || v === 'notification' || v === 'message-extension'
|
|
544
557
|
? true
|
|
545
|
-
: `Unknown bot kind ${JSON.stringify(v)}. One of: echo, notification.`,
|
|
558
|
+
: `Unknown bot kind ${JSON.stringify(v)}. One of: echo, notification, message-extension.`,
|
|
546
559
|
},
|
|
547
560
|
],
|
|
548
561
|
// Default the bot kind so programmatic callers that omit the answer still resolve a variant.
|
|
@@ -555,6 +568,7 @@ export const ARTIFACTS = [
|
|
|
555
568
|
cases: {
|
|
556
569
|
echo: '_variants/bot.echo',
|
|
557
570
|
notification: '_variants/bot.notification',
|
|
571
|
+
'message-extension': '_variants/bot.message-extension',
|
|
558
572
|
},
|
|
559
573
|
to: '.',
|
|
560
574
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/artifacts/registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/artifacts/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -30,8 +30,8 @@ program
|
|
|
30
30
|
.option('--component-name <name>', 'component name for PCF control')
|
|
31
31
|
.option('--property-type <type>', 'PCF bound property type (e.g. SingleLine.Text, TwoOptions)')
|
|
32
32
|
.option('--graph', 'include Microsoft Graph integration (teams-app)')
|
|
33
|
-
.option('--tab-kind <kind>', 'teams-app tab kind: basic (default), sso, or
|
|
34
|
-
.option('--bot-kind <kind>', 'teams-bot bot kind: echo (default) or
|
|
33
|
+
.option('--tab-kind <kind>', 'teams-app tab kind: basic (default), sso, dashboard, or meeting')
|
|
34
|
+
.option('--bot-kind <kind>', 'teams-bot bot kind: echo (default), notification, or message-extension')
|
|
35
35
|
.option('--surface <surface>', 'starter-page surface: form, panel, dashboard, master-detail')
|
|
36
36
|
.option('--host <host>', 'host-swap target: custom-page (default), pcf, or web-resource')
|
|
37
37
|
.option('--with-components', 'install @khester/reusable-components (Fluent v8) — power-pages, web-resource, dialog-form')
|
|
@@ -162,9 +162,22 @@ program
|
|
|
162
162
|
}
|
|
163
163
|
else if (descriptor.id === 'teams-bot') {
|
|
164
164
|
console.log(' cp .env.example .env # MOCK_MODE=true — no Azure needed');
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
if (vars?.botKind === 'message-extension') {
|
|
166
|
+
console.log(' npm run dev # Message-extension server on http://localhost:3978');
|
|
167
|
+
console.log(' # invoke it from the Teams compose box (search / action / link) — not a console');
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.log(' npm run dev -- --interactive # Console chat with the bot logic');
|
|
171
|
+
console.log(' npm run dev # Bot server on http://localhost:3978');
|
|
172
|
+
}
|
|
173
|
+
console.log('\n🚀 Ship to Azure + Teams: teams-app-manager.sh up --project . --sideload');
|
|
174
|
+
}
|
|
175
|
+
else if (descriptor.id === 'teams-app' && vars?.tabKind === 'meeting') {
|
|
176
|
+
console.log(' npm run dev # Start development server (side panel view)');
|
|
177
|
+
console.log(' npm run build # Build for production');
|
|
167
178
|
console.log('\n🚀 Ship to Azure + Teams: teams-app-manager.sh up --project . --sideload');
|
|
179
|
+
console.log(' # then add the app as a tab INSIDE a Teams meeting (desktop) for the');
|
|
180
|
+
console.log(' # side panel + Share to Stage — a personal sideload is not a meeting.');
|
|
168
181
|
}
|
|
169
182
|
else {
|
|
170
183
|
console.log(' npm run dev # Start development server');
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAmB,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EACL,WAAW,EAEX,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,qBAAqB,CAAC;KAC3B,WAAW,CAAC,gEAAgE,CAAC;KAC7E,OAAO,CAAC,WAAW,CAAC;KACpB,QAAQ,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;KACjD,MAAM,CACL,qBAAqB,EACrB,kBAAkB,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACtF;KACA,MAAM,CAAC,2BAA2B,EAAE,mCAAmC,CAAC;KACxE,MAAM,CAAC,yBAAyB,EAAE,qDAAqD,CAAC;KACxF,MAAM,CAAC,MAAM,EAAE,mCAAmC,CAAC;KACnD,MAAM,CAAC,MAAM,EAAE,mCAAmC,CAAC;KACnD,MAAM,CAAC,6BAA6B,EAAE,2BAA2B,CAAC;KAClE,MAAM,CAAC,yBAAyB,EAAE,gCAAgC,CAAC;KACnE,MAAM,CAAC,wBAAwB,EAAE,4DAA4D,CAAC;KAC9F,MAAM,CAAC,SAAS,EAAE,iDAAiD,CAAC;KACpE,MAAM,CAAC,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ A **Microsoft Teams tab** — React + Fluent UI v9 + `@microsoft/teams-js`, scaf
|
|
|
8
8
|
| `basic` | Personal tab showing the Teams context — no auth. |
|
|
9
9
|
| `sso` | Teams single sign-on (`getAuthToken`) with an MSAL browser fallback + `auth.html` bridge for interactive sign-in inside Teams. |
|
|
10
10
|
| `dashboard` | Configurable channel/personal dashboard: widget grid, `/#/config` page wired to `pages.config`, theme-aware. SSO-capable (ships `useTeamsAuth`). |
|
|
11
|
+
| `meeting` | In-meeting app: side panel + shared stage, chosen by the Teams `frameContext`, with `shareAppContentToStage`. Configurable meeting tab (`/#/config`), theme-aware. SSO-capable (ships `useTeamsAuth`). Requires the `MeetingStage.Write.Chat` RSC permission (in the manifest). |
|
|
11
12
|
|
|
12
13
|
## Develop
|
|
13
14
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.19/MicrosoftTeams.schema.json",
|
|
3
|
+
"manifestVersion": "1.19",
|
|
4
|
+
"id": "{{TEAMS_APP_ID}}",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"developer": {
|
|
7
|
+
"name": "Contoso",
|
|
8
|
+
"websiteUrl": "https://example.com",
|
|
9
|
+
"privacyUrl": "https://example.com/privacy",
|
|
10
|
+
"termsOfUseUrl": "https://example.com/terms"
|
|
11
|
+
},
|
|
12
|
+
"name": { "short": "{{projectName}}", "full": "{{projectName}}" },
|
|
13
|
+
"description": { "short": "{{projectName}} meeting app", "full": "{{projectName}} in-meeting Microsoft Teams tab — side panel and shared stage" },
|
|
14
|
+
"icons": { "color": "color.png", "outline": "outline.png" },
|
|
15
|
+
"accentColor": "#6264A7",
|
|
16
|
+
"staticTabs": [
|
|
17
|
+
{
|
|
18
|
+
"entityId": "home",
|
|
19
|
+
"name": "{{projectName}}",
|
|
20
|
+
"contentUrl": "https://{{HOSTNAME}}/",
|
|
21
|
+
"websiteUrl": "https://{{HOSTNAME}}/",
|
|
22
|
+
"scopes": ["personal"]
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"configurableTabs": [
|
|
26
|
+
{
|
|
27
|
+
"configurationUrl": "https://{{HOSTNAME}}/#/config",
|
|
28
|
+
"canUpdateConfiguration": true,
|
|
29
|
+
"scopes": ["groupChat"],
|
|
30
|
+
"context": ["meetingSidePanel", "meetingStage"]
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"permissions": ["identity"],
|
|
34
|
+
"validDomains": ["{{HOSTNAME}}"],
|
|
35
|
+
"webApplicationInfo": {
|
|
36
|
+
"id": "{{CLIENT_ID}}",
|
|
37
|
+
"resource": "api://{{HOSTNAME}}/{{CLIENT_ID}}"
|
|
38
|
+
},
|
|
39
|
+
"authorization": {
|
|
40
|
+
"permissions": {
|
|
41
|
+
"resourceSpecific": [
|
|
42
|
+
{ "name": "MeetingStage.Write.Chat", "type": "Delegated" }
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>{{projectName}} — Sign in</title>
|
|
7
|
+
<style>
|
|
8
|
+
body { font-family: system-ui, -apple-system, "Segoe UI", sans-serif; padding: 24px; color: #555; }
|
|
9
|
+
</style>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<p id="status">Working…</p>
|
|
13
|
+
<script type="module" src="/src/auth-bridge.ts"></script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
FluentProvider,
|
|
4
|
+
teamsLightTheme,
|
|
5
|
+
teamsDarkTheme,
|
|
6
|
+
teamsHighContrastTheme,
|
|
7
|
+
type Theme,
|
|
8
|
+
Spinner,
|
|
9
|
+
} from '@fluentui/react-components';
|
|
10
|
+
import { app } from '@microsoft/teams-js';
|
|
11
|
+
import { useHashRoute } from './hooks/useHashRoute';
|
|
12
|
+
import { SidePanel } from './components/SidePanel';
|
|
13
|
+
import { StageView } from './components/StageView';
|
|
14
|
+
import { Config } from './pages/Config';
|
|
15
|
+
import { Remove } from './pages/Remove';
|
|
16
|
+
|
|
17
|
+
const THEMES: Record<string, Theme> = {
|
|
18
|
+
default: teamsLightTheme,
|
|
19
|
+
dark: teamsDarkTheme,
|
|
20
|
+
contrast: teamsHighContrastTheme,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A Teams meeting app: one SPA that renders the in-meeting side panel or the
|
|
25
|
+
* shared stage depending on the frameContext Teams reports. Route precedence is
|
|
26
|
+
* load-bearing — the tab-configuration page loads at `/#/config` with
|
|
27
|
+
* frameContext `settings`, so `/config` and `/remove` must be matched BEFORE the
|
|
28
|
+
* meetingStage/sidePanel switch, or the config dialog would render the SidePanel.
|
|
29
|
+
*/
|
|
30
|
+
export const App: React.FC = () => {
|
|
31
|
+
const route = useHashRoute();
|
|
32
|
+
const [theme, setTheme] = React.useState<Theme>(teamsLightTheme);
|
|
33
|
+
const [frameContext, setFrameContext] = React.useState<string>('sidePanel');
|
|
34
|
+
const [initialized, setInitialized] = React.useState(false);
|
|
35
|
+
|
|
36
|
+
React.useEffect(() => {
|
|
37
|
+
const init = async () => {
|
|
38
|
+
try {
|
|
39
|
+
await app.initialize();
|
|
40
|
+
const context = await app.getContext();
|
|
41
|
+
setTheme(THEMES[context.app.theme] ?? teamsLightTheme);
|
|
42
|
+
setFrameContext(context.page?.frameContext ?? 'sidePanel');
|
|
43
|
+
app.registerOnThemeChangeHandler((t) => setTheme(THEMES[t] ?? teamsLightTheme));
|
|
44
|
+
} catch {
|
|
45
|
+
// Standalone browser mode — keep the light theme and the sidePanel view.
|
|
46
|
+
}
|
|
47
|
+
setInitialized(true);
|
|
48
|
+
};
|
|
49
|
+
void init();
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
let page: React.ReactNode;
|
|
53
|
+
if (route === '/config') page = <Config />;
|
|
54
|
+
else if (route === '/remove') page = <Remove />;
|
|
55
|
+
else if (!initialized) page = <Spinner label="Loading…" />;
|
|
56
|
+
else page = frameContext === 'meetingStage' ? <StageView /> : <SidePanel />;
|
|
57
|
+
|
|
58
|
+
return <FluentProvider theme={theme}>{page}</FluentProvider>;
|
|
59
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { app, authentication } from '@microsoft/teams-js';
|
|
2
|
+
import { PublicClientApplication } from '@azure/msal-browser';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Auth bridge — loaded by auth.html inside the window Teams opens for
|
|
6
|
+
* `authentication.authenticate()`. MSAL's popup flow is blocked inside the Teams
|
|
7
|
+
* tab iframe, so interactive sign-in happens here: loginRedirect → back to this
|
|
8
|
+
* page → handleRedirectPromise → notifySuccess back to the tab.
|
|
9
|
+
*/
|
|
10
|
+
const setStatus = (msg: string): void => {
|
|
11
|
+
const el = document.getElementById('status');
|
|
12
|
+
if (el) el.textContent = msg;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
(async () => {
|
|
16
|
+
try {
|
|
17
|
+
await app.initialize();
|
|
18
|
+
|
|
19
|
+
const clientId = import.meta.env.VITE_CLIENT_ID ?? '';
|
|
20
|
+
const tenantId = import.meta.env.VITE_TENANT_ID ?? 'common';
|
|
21
|
+
if (!clientId) throw new Error('VITE_CLIENT_ID is not set — copy env.local.template to .env.local');
|
|
22
|
+
|
|
23
|
+
const pca = new PublicClientApplication({
|
|
24
|
+
auth: {
|
|
25
|
+
clientId,
|
|
26
|
+
authority: `https://login.microsoftonline.com/${tenantId}`,
|
|
27
|
+
redirectUri: `${window.location.origin}/auth.html`,
|
|
28
|
+
},
|
|
29
|
+
cache: { cacheLocation: 'localStorage' },
|
|
30
|
+
});
|
|
31
|
+
await pca.initialize();
|
|
32
|
+
|
|
33
|
+
setStatus('Completing sign-in…');
|
|
34
|
+
const response = await pca.handleRedirectPromise();
|
|
35
|
+
if (response?.account) {
|
|
36
|
+
setStatus(`Signed in as ${response.account.username}`);
|
|
37
|
+
authentication.notifySuccess(response.account.username);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setStatus('Redirecting to sign in…');
|
|
42
|
+
await pca.loginRedirect({ scopes: ['User.Read'] });
|
|
43
|
+
} catch (err) {
|
|
44
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
45
|
+
setStatus(`Sign-in failed: ${msg}`);
|
|
46
|
+
try {
|
|
47
|
+
authentication.notifyFailure(msg);
|
|
48
|
+
} catch {
|
|
49
|
+
// Outside a Teams auth window — the status line above is the surface.
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
})();
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Card,
|
|
4
|
+
CardHeader,
|
|
5
|
+
Text,
|
|
6
|
+
Button,
|
|
7
|
+
makeStyles,
|
|
8
|
+
tokens,
|
|
9
|
+
Input,
|
|
10
|
+
Badge,
|
|
11
|
+
MessageBar,
|
|
12
|
+
MessageBarBody,
|
|
13
|
+
} from '@fluentui/react-components';
|
|
14
|
+
import { People24Regular, Share24Regular, Send24Regular } from '@fluentui/react-icons';
|
|
15
|
+
import { meeting } from '@microsoft/teams-js';
|
|
16
|
+
|
|
17
|
+
const useStyles = makeStyles({
|
|
18
|
+
container: { padding: tokens.spacingHorizontalL, minHeight: '100vh' },
|
|
19
|
+
header: { marginBottom: tokens.spacingVerticalL },
|
|
20
|
+
card: { marginBottom: tokens.spacingVerticalM },
|
|
21
|
+
input: { display: 'flex', gap: tokens.spacingHorizontalS, marginTop: tokens.spacingVerticalM },
|
|
22
|
+
messages: { maxHeight: '200px', overflowY: 'auto', marginBottom: tokens.spacingVerticalM },
|
|
23
|
+
message: {
|
|
24
|
+
padding: tokens.spacingHorizontalS,
|
|
25
|
+
background: tokens.colorNeutralBackground3,
|
|
26
|
+
borderRadius: '4px',
|
|
27
|
+
marginBottom: tokens.spacingVerticalXS,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The in-meeting side panel. "Share to Stage" shares the app's ROOT url onto the
|
|
33
|
+
* meeting stage — Teams re-opens it with frameContext `meetingStage`, so App.tsx
|
|
34
|
+
* renders <StageView/>. (The 07 teaching sample shared `/stage`, which 404s on a
|
|
35
|
+
* static SWA host and is never routed.) The shareAppContentToStage callback is
|
|
36
|
+
* `(error, result)` — surface the error instead of discarding it, or a failed
|
|
37
|
+
* share (e.g. a missing MeetingStage.Write.Chat RSC grant) is silent.
|
|
38
|
+
*/
|
|
39
|
+
export function SidePanel() {
|
|
40
|
+
const styles = useStyles();
|
|
41
|
+
const [messages, setMessages] = useState<string[]>(['Meeting started', 'Welcome everyone!']);
|
|
42
|
+
const [newMessage, setNewMessage] = useState('');
|
|
43
|
+
const [shareError, setShareError] = useState<string | null>(null);
|
|
44
|
+
|
|
45
|
+
const handleShare = () => {
|
|
46
|
+
setShareError(null);
|
|
47
|
+
try {
|
|
48
|
+
meeting.shareAppContentToStage((error) => {
|
|
49
|
+
if (error) {
|
|
50
|
+
console.error('shareAppContentToStage failed:', error);
|
|
51
|
+
setShareError(error.message ?? 'Could not share to the meeting stage.');
|
|
52
|
+
}
|
|
53
|
+
}, `${window.location.origin}/#/`);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
console.error('Share to stage:', e);
|
|
56
|
+
setShareError('Sharing to the stage is only available inside a Teams meeting (desktop).');
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const sendMessage = () => {
|
|
61
|
+
if (newMessage.trim()) {
|
|
62
|
+
setMessages([...messages, newMessage]);
|
|
63
|
+
setNewMessage('');
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className={styles.container}>
|
|
69
|
+
<div className={styles.header}>
|
|
70
|
+
<Text size={500} weight="semibold">
|
|
71
|
+
Meeting Side Panel
|
|
72
|
+
</Text>
|
|
73
|
+
<Badge appearance="filled" color="success" style={{ marginLeft: 8 }}>
|
|
74
|
+
Live
|
|
75
|
+
</Badge>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<Card className={styles.card}>
|
|
79
|
+
<CardHeader
|
|
80
|
+
header={
|
|
81
|
+
<Text weight="semibold">
|
|
82
|
+
<People24Regular /> Participants
|
|
83
|
+
</Text>
|
|
84
|
+
}
|
|
85
|
+
/>
|
|
86
|
+
<div style={{ padding: tokens.spacingHorizontalM }}>
|
|
87
|
+
<Text>3 participants in meeting</Text>
|
|
88
|
+
</div>
|
|
89
|
+
</Card>
|
|
90
|
+
|
|
91
|
+
<Card className={styles.card}>
|
|
92
|
+
<CardHeader header={<Text weight="semibold">Meeting Chat</Text>} />
|
|
93
|
+
<div style={{ padding: tokens.spacingHorizontalM }}>
|
|
94
|
+
<div className={styles.messages}>
|
|
95
|
+
{messages.map((m, i) => (
|
|
96
|
+
<div key={i} className={styles.message}>
|
|
97
|
+
<Text size={200}>{m}</Text>
|
|
98
|
+
</div>
|
|
99
|
+
))}
|
|
100
|
+
</div>
|
|
101
|
+
<div className={styles.input}>
|
|
102
|
+
<Input
|
|
103
|
+
value={newMessage}
|
|
104
|
+
onChange={(_, d) => setNewMessage(d.value)}
|
|
105
|
+
placeholder="Type a message..."
|
|
106
|
+
style={{ flex: 1 }}
|
|
107
|
+
/>
|
|
108
|
+
<Button icon={<Send24Regular />} onClick={sendMessage} />
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</Card>
|
|
112
|
+
|
|
113
|
+
<Button appearance="primary" icon={<Share24Regular />} onClick={handleShare}>
|
|
114
|
+
Share to Stage
|
|
115
|
+
</Button>
|
|
116
|
+
|
|
117
|
+
{shareError && (
|
|
118
|
+
<MessageBar intent="error" style={{ marginTop: tokens.spacingVerticalM }}>
|
|
119
|
+
<MessageBarBody>{shareError}</MessageBarBody>
|
|
120
|
+
</MessageBar>
|
|
121
|
+
)}
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Card, Text, Button, makeStyles, tokens, Badge } from '@fluentui/react-components';
|
|
3
|
+
import { Play24Regular, Pause24Regular, Next24Regular, Previous24Regular } from '@fluentui/react-icons';
|
|
4
|
+
|
|
5
|
+
const useStyles = makeStyles({
|
|
6
|
+
container: {
|
|
7
|
+
padding: tokens.spacingHorizontalXXL,
|
|
8
|
+
textAlign: 'center',
|
|
9
|
+
minHeight: '100vh',
|
|
10
|
+
display: 'flex',
|
|
11
|
+
flexDirection: 'column',
|
|
12
|
+
alignItems: 'center',
|
|
13
|
+
justifyContent: 'center',
|
|
14
|
+
},
|
|
15
|
+
title: { marginBottom: tokens.spacingVerticalL },
|
|
16
|
+
card: { maxWidth: '600px', width: '100%', padding: tokens.spacingHorizontalL },
|
|
17
|
+
slide: {
|
|
18
|
+
background: tokens.colorNeutralBackground3,
|
|
19
|
+
borderRadius: '8px',
|
|
20
|
+
padding: tokens.spacingHorizontalXXL,
|
|
21
|
+
marginBottom: tokens.spacingVerticalL,
|
|
22
|
+
minHeight: '200px',
|
|
23
|
+
display: 'flex',
|
|
24
|
+
alignItems: 'center',
|
|
25
|
+
justifyContent: 'center',
|
|
26
|
+
},
|
|
27
|
+
controls: { display: 'flex', gap: tokens.spacingHorizontalM, justifyContent: 'center' },
|
|
28
|
+
status: { marginTop: tokens.spacingVerticalM },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const slides = [
|
|
32
|
+
{ title: 'Welcome', content: 'Welcome to the meeting presentation' },
|
|
33
|
+
{ title: 'Agenda', content: 'Today we will cover: Q4 results, roadmap, Q&A' },
|
|
34
|
+
{ title: 'Results', content: 'Q4 exceeded expectations by 15%' },
|
|
35
|
+
{ title: 'Thank You', content: 'Questions?' },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The shared meeting stage. Reached when Teams opens the app on the stage
|
|
40
|
+
* (frameContext === 'meetingStage'); pure presentational, no teams-js calls.
|
|
41
|
+
*/
|
|
42
|
+
export function StageView() {
|
|
43
|
+
const styles = useStyles();
|
|
44
|
+
const [currentSlide, setCurrentSlide] = useState(0);
|
|
45
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
46
|
+
|
|
47
|
+
const next = () => setCurrentSlide((c) => Math.min(c + 1, slides.length - 1));
|
|
48
|
+
const prev = () => setCurrentSlide((c) => Math.max(c - 1, 0));
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className={styles.container}>
|
|
52
|
+
<Text size={600} weight="semibold" className={styles.title}>
|
|
53
|
+
Meeting Stage
|
|
54
|
+
</Text>
|
|
55
|
+
<Badge appearance="filled" color="brand">
|
|
56
|
+
Shared with everyone
|
|
57
|
+
</Badge>
|
|
58
|
+
|
|
59
|
+
<Card className={styles.card}>
|
|
60
|
+
<div className={styles.slide}>
|
|
61
|
+
<div>
|
|
62
|
+
<Text size={500} weight="semibold" block>
|
|
63
|
+
{slides[currentSlide].title}
|
|
64
|
+
</Text>
|
|
65
|
+
<Text size={300} style={{ marginTop: 16 }}>
|
|
66
|
+
{slides[currentSlide].content}
|
|
67
|
+
</Text>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div className={styles.controls}>
|
|
72
|
+
<Button icon={<Previous24Regular />} onClick={prev} disabled={currentSlide === 0} />
|
|
73
|
+
<Button
|
|
74
|
+
icon={isPlaying ? <Pause24Regular /> : <Play24Regular />}
|
|
75
|
+
appearance="primary"
|
|
76
|
+
onClick={() => setIsPlaying(!isPlaying)}
|
|
77
|
+
/>
|
|
78
|
+
<Button
|
|
79
|
+
icon={<Next24Regular />}
|
|
80
|
+
onClick={next}
|
|
81
|
+
disabled={currentSlide === slides.length - 1}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div className={styles.status}>
|
|
86
|
+
<Text size={200}>
|
|
87
|
+
Slide {currentSlide + 1} of {slides.length}
|
|
88
|
+
</Text>
|
|
89
|
+
</div>
|
|
90
|
+
</Card>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tiny hash router — `#/config` → `/config`. Hash routing keeps the tab a single
|
|
5
|
+
* static bundle (no server rewrites needed on Static Web Apps), which is why the
|
|
6
|
+
* manifest's configurationUrl points at `/#/config`.
|
|
7
|
+
*/
|
|
8
|
+
export function useHashRoute(): string {
|
|
9
|
+
const [hash, setHash] = useState(window.location.hash);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const onChange = () => setHash(window.location.hash);
|
|
12
|
+
window.addEventListener('hashchange', onChange);
|
|
13
|
+
return () => window.removeEventListener('hashchange', onChange);
|
|
14
|
+
}, []);
|
|
15
|
+
return hash.replace(/^#/, '') || '/';
|
|
16
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { app, authentication } from '@microsoft/teams-js';
|
|
3
|
+
import { PublicClientApplication, type AccountInfo } from '@azure/msal-browser';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Teams-first auth: try Teams SSO (`authentication.getAuthToken()`), fall back to
|
|
7
|
+
* MSAL. Inside the Teams iframe, interactive sign-in must go through the auth
|
|
8
|
+
* bridge (`auth.html`) — `loginPopup` is blocked there; outside Teams (plain
|
|
9
|
+
* browser tab) MSAL redirect works directly.
|
|
10
|
+
*
|
|
11
|
+
* VITE_CLIENT_ID / VITE_TENANT_ID come from `.env.local` (see env.local.template);
|
|
12
|
+
* `teams-app-manager.sh identity` writes them after registering the Entra app.
|
|
13
|
+
*/
|
|
14
|
+
const clientId = import.meta.env.VITE_CLIENT_ID ?? '';
|
|
15
|
+
const tenantId = import.meta.env.VITE_TENANT_ID ?? 'common';
|
|
16
|
+
|
|
17
|
+
const msalInstance = new PublicClientApplication({
|
|
18
|
+
auth: {
|
|
19
|
+
clientId,
|
|
20
|
+
authority: `https://login.microsoftonline.com/${tenantId}`,
|
|
21
|
+
redirectUri: window.location.origin,
|
|
22
|
+
},
|
|
23
|
+
cache: { cacheLocation: 'localStorage' },
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export interface AuthState {
|
|
27
|
+
token: string | null;
|
|
28
|
+
account: AccountInfo | null;
|
|
29
|
+
inTeams: boolean;
|
|
30
|
+
loading: boolean;
|
|
31
|
+
error: Error | null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function useTeamsAuth(): AuthState & { login: () => Promise<void> } {
|
|
35
|
+
const [state, setState] = useState<AuthState>({
|
|
36
|
+
token: null,
|
|
37
|
+
account: null,
|
|
38
|
+
inTeams: false,
|
|
39
|
+
loading: true,
|
|
40
|
+
error: null,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const getToken = useCallback(async () => {
|
|
44
|
+
// 1. Teams SSO — works once the app registration exposes api://{host}/{clientId}
|
|
45
|
+
// with the Teams client ids pre-authorized.
|
|
46
|
+
try {
|
|
47
|
+
await app.initialize();
|
|
48
|
+
const ssoToken = await authentication.getAuthToken();
|
|
49
|
+
setState({ token: ssoToken, account: null, inTeams: true, loading: false, error: null });
|
|
50
|
+
return;
|
|
51
|
+
} catch {
|
|
52
|
+
// Not in Teams, or SSO not consented yet — fall through to MSAL.
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 2. MSAL silent — a previous interactive sign-in left an account in the cache.
|
|
56
|
+
try {
|
|
57
|
+
await msalInstance.initialize();
|
|
58
|
+
const redirect = await msalInstance.handleRedirectPromise().catch(() => null);
|
|
59
|
+
const account = redirect?.account ?? msalInstance.getAllAccounts()[0];
|
|
60
|
+
if (account) {
|
|
61
|
+
const result = await msalInstance.acquireTokenSilent({
|
|
62
|
+
scopes: ['User.Read'],
|
|
63
|
+
account,
|
|
64
|
+
});
|
|
65
|
+
setState({
|
|
66
|
+
token: result.accessToken,
|
|
67
|
+
account: result.account,
|
|
68
|
+
inTeams: false,
|
|
69
|
+
loading: false,
|
|
70
|
+
error: null,
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
setState((prev) => ({ ...prev, loading: false }));
|
|
75
|
+
} catch (error) {
|
|
76
|
+
setState((prev) => ({ ...prev, loading: false, error: error as Error }));
|
|
77
|
+
}
|
|
78
|
+
}, []);
|
|
79
|
+
|
|
80
|
+
/** Interactive sign-in. In Teams → auth bridge popup; in a browser → MSAL redirect. */
|
|
81
|
+
const login = useCallback(async () => {
|
|
82
|
+
if (!clientId) {
|
|
83
|
+
setState((prev) => ({
|
|
84
|
+
...prev,
|
|
85
|
+
error: new Error('VITE_CLIENT_ID is not set — copy env.local.template to .env.local'),
|
|
86
|
+
}));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let inTeams = false;
|
|
90
|
+
try {
|
|
91
|
+
await app.initialize();
|
|
92
|
+
inTeams = true;
|
|
93
|
+
} catch {
|
|
94
|
+
// Plain browser tab.
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
if (inTeams) {
|
|
99
|
+
// Teams opens auth.html in a real window where MSAL's redirect flow is
|
|
100
|
+
// allowed; the bridge calls notifySuccess/notifyFailure when done.
|
|
101
|
+
await authentication.authenticate({
|
|
102
|
+
url: `${window.location.origin}/auth.html`,
|
|
103
|
+
width: 600,
|
|
104
|
+
height: 535,
|
|
105
|
+
});
|
|
106
|
+
await getToken();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
await msalInstance.initialize();
|
|
110
|
+
await msalInstance.loginRedirect({ scopes: ['User.Read'] });
|
|
111
|
+
} catch (error) {
|
|
112
|
+
setState((prev) => ({ ...prev, error: error as Error }));
|
|
113
|
+
}
|
|
114
|
+
}, [getToken]);
|
|
115
|
+
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
void getToken();
|
|
118
|
+
}, [getToken]);
|
|
119
|
+
|
|
120
|
+
return { ...state, login };
|
|
121
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Text, MessageBar, MessageBarBody } from '@fluentui/react-components';
|
|
3
|
+
import { app, pages } from '@microsoft/teams-js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The tab-configuration page (manifest configurableTabs.configurationUrl → /#/config),
|
|
7
|
+
* shown when someone adds the app as an in-meeting tab. A meeting tab has no per-channel
|
|
8
|
+
* settings to collect, so this just registers a save handler that pins the content URL —
|
|
9
|
+
* the app itself picks the side-panel vs stage view from the Teams frameContext at runtime.
|
|
10
|
+
*/
|
|
11
|
+
export const Config: React.FC = () => {
|
|
12
|
+
const [inTeams, setInTeams] = React.useState(false);
|
|
13
|
+
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
const init = async () => {
|
|
16
|
+
try {
|
|
17
|
+
await app.initialize();
|
|
18
|
+
setInTeams(true);
|
|
19
|
+
pages.config.registerOnSaveHandler((saveEvent) => {
|
|
20
|
+
// First-time configuration has no page id yet, so mint a unique entityId;
|
|
21
|
+
// it returns as context.page.id when the pinned tab loads.
|
|
22
|
+
const entityId = `meeting-${Date.now()}`;
|
|
23
|
+
void pages.config
|
|
24
|
+
.setConfig({
|
|
25
|
+
suggestedDisplayName: 'Meeting App',
|
|
26
|
+
entityId,
|
|
27
|
+
contentUrl: `${window.location.origin}/`,
|
|
28
|
+
websiteUrl: `${window.location.origin}/`,
|
|
29
|
+
removeUrl: `${window.location.origin}/#/remove`,
|
|
30
|
+
})
|
|
31
|
+
.then(() => saveEvent.notifySuccess())
|
|
32
|
+
.catch(() => saveEvent.notifyFailure('Failed to save the meeting tab configuration'));
|
|
33
|
+
});
|
|
34
|
+
void pages.config.setValidityState(true);
|
|
35
|
+
} catch {
|
|
36
|
+
setInTeams(false);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
void init();
|
|
40
|
+
}, []);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, padding: 16, maxWidth: 480 }}>
|
|
44
|
+
<Text size={500} weight="semibold">
|
|
45
|
+
Add to meeting
|
|
46
|
+
</Text>
|
|
47
|
+
<Text>
|
|
48
|
+
This app runs in the meeting side panel and can share content to the meeting stage. Select
|
|
49
|
+
Save to add it.
|
|
50
|
+
</Text>
|
|
51
|
+
{!inTeams && (
|
|
52
|
+
<MessageBar intent="info">
|
|
53
|
+
<MessageBarBody>
|
|
54
|
+
Running outside Teams — add this app from within a Teams meeting to configure it.
|
|
55
|
+
</MessageBarBody>
|
|
56
|
+
</MessageBar>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Text } from '@fluentui/react-components';
|
|
3
|
+
|
|
4
|
+
/** Shown by Teams when the tab is removed (configurableTabs removeUrl). */
|
|
5
|
+
export const Remove: React.FC = () => (
|
|
6
|
+
<div style={{ padding: 16 }}>
|
|
7
|
+
<Text>Removing this tab removes the app from this meeting. The app itself stays installed.</Text>
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import react from '@vitejs/plugin-react';
|
|
3
|
+
import { fileURLToPath, URL } from 'node:url';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
// Teams tabs must be served over HTTPS; `vite --https` or a tunnel in dev.
|
|
8
|
+
server: { port: 3000 },
|
|
9
|
+
build: {
|
|
10
|
+
outDir: 'dist',
|
|
11
|
+
rollupOptions: {
|
|
12
|
+
// MPA: the tab plus the auth bridge Teams opens for interactive sign-in.
|
|
13
|
+
input: {
|
|
14
|
+
main: fileURLToPath(new URL('./index.html', import.meta.url)),
|
|
15
|
+
auth: fileURLToPath(new URL('./auth.html', import.meta.url)),
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
@@ -14,5 +14,6 @@ NOTIFY_API_KEY=
|
|
|
14
14
|
CONVERSATION_STORE_PATH=./.data/conversations.json
|
|
15
15
|
|
|
16
16
|
PORT=3978
|
|
17
|
-
# Mock mode runs the bot without any Azure registration
|
|
17
|
+
# Mock mode runs the bot without any Azure registration.
|
|
18
|
+
# (echo / notification kinds: try a console loop with `npm run dev -- --interactive`)
|
|
18
19
|
MOCK_MODE=true
|
|
@@ -8,18 +8,26 @@ scaffolded by `create-dynamics-app --artifact teams-bot`.
|
|
|
8
8
|
```bash
|
|
9
9
|
cp .env.example .env # MOCK_MODE=true is the default
|
|
10
10
|
npm install
|
|
11
|
-
npm run dev
|
|
12
|
-
npm run dev # or: run the HTTP server on http://localhost:3978
|
|
11
|
+
npm run dev # HTTP server on http://localhost:3978
|
|
13
12
|
```
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
The **echo** and **notification** kinds can also drive the bot logic through a console
|
|
15
|
+
chat loop with no server:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm run dev -- --interactive # echo / notification only
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The **message-extension** kind has no console loop — it is invoked from the Teams compose
|
|
22
|
+
box (search / action / link unfurling), so run the HTTP server and sideload the app package.
|
|
23
|
+
|
|
24
|
+
Mock mode needs no app registration and no tunnel. The HTTP server exposes:
|
|
17
25
|
|
|
18
26
|
| Endpoint | Purpose |
|
|
19
27
|
|----------|---------|
|
|
20
|
-
| `POST /api/messages` | Bot Framework messaging endpoint |
|
|
28
|
+
| `POST /api/messages` | Bot Framework messaging endpoint (bot messages + compose-extension queries/actions) |
|
|
21
29
|
| `GET /health` | Health probe (used by the deploy pipeline) |
|
|
22
|
-
| `POST /api/notify` | Proactive notifications (notification
|
|
30
|
+
| `POST /api/notify` | Proactive notifications (notification kind only; requires the `X-Notify-Key` header) |
|
|
23
31
|
|
|
24
32
|
## Ship it to Azure + Teams
|
|
25
33
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.19/MicrosoftTeams.schema.json",
|
|
3
|
+
"manifestVersion": "1.19",
|
|
4
|
+
"id": "{{TEAMS_APP_ID}}",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"developer": {
|
|
7
|
+
"name": "Contoso",
|
|
8
|
+
"websiteUrl": "https://example.com",
|
|
9
|
+
"privacyUrl": "https://example.com/privacy",
|
|
10
|
+
"termsOfUseUrl": "https://example.com/terms"
|
|
11
|
+
},
|
|
12
|
+
"name": { "short": "{{projectName}}", "full": "{{projectName}}" },
|
|
13
|
+
"description": { "short": "{{projectName}} message extension", "full": "{{projectName}} — a Microsoft Teams message extension: search sample data from the compose box, create items via a task module, and unfurl links" },
|
|
14
|
+
"icons": { "color": "color.png", "outline": "outline.png" },
|
|
15
|
+
"accentColor": "#6264A7",
|
|
16
|
+
"composeExtensions": [
|
|
17
|
+
{
|
|
18
|
+
"botId": "{{BOT_ID}}",
|
|
19
|
+
"canUpdateConfiguration": false,
|
|
20
|
+
"commands": [
|
|
21
|
+
{
|
|
22
|
+
"id": "searchCommand",
|
|
23
|
+
"type": "query",
|
|
24
|
+
"title": "Search",
|
|
25
|
+
"description": "Search sample data",
|
|
26
|
+
"initialRun": true,
|
|
27
|
+
"context": ["commandBox", "compose"],
|
|
28
|
+
"parameters": [
|
|
29
|
+
{
|
|
30
|
+
"name": "query",
|
|
31
|
+
"title": "Search query",
|
|
32
|
+
"description": "Enter search terms"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "createCommand",
|
|
38
|
+
"type": "action",
|
|
39
|
+
"title": "Create",
|
|
40
|
+
"description": "Create a new item",
|
|
41
|
+
"fetchTask": true,
|
|
42
|
+
"context": ["commandBox", "compose"]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"messageHandlers": [
|
|
46
|
+
{
|
|
47
|
+
"type": "link",
|
|
48
|
+
"value": {
|
|
49
|
+
"domains": ["*.example.com"]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"permissions": ["identity"]
|
|
56
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TeamsActivityHandler,
|
|
3
|
+
TurnContext,
|
|
4
|
+
MessagingExtensionQuery,
|
|
5
|
+
MessagingExtensionResponse,
|
|
6
|
+
MessagingExtensionAction,
|
|
7
|
+
MessagingExtensionActionResponse,
|
|
8
|
+
CardFactory,
|
|
9
|
+
TaskModuleResponse,
|
|
10
|
+
} from 'botbuilder';
|
|
11
|
+
import { searchProducts, mockProducts, IProduct } from '../mock/mockData';
|
|
12
|
+
|
|
13
|
+
export class MessageExtensionBot extends TeamsActivityHandler {
|
|
14
|
+
// Handle search-based message extension
|
|
15
|
+
protected async handleTeamsMessagingExtensionQuery(
|
|
16
|
+
context: TurnContext,
|
|
17
|
+
query: MessagingExtensionQuery
|
|
18
|
+
): Promise<MessagingExtensionResponse> {
|
|
19
|
+
const searchQuery = query.parameters?.[0]?.value || '';
|
|
20
|
+
const results = searchQuery ? searchProducts(searchQuery) : mockProducts.slice(0, 5);
|
|
21
|
+
|
|
22
|
+
const attachments = results.map((product) => this.createProductCard(product));
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
composeExtension: {
|
|
26
|
+
type: 'result',
|
|
27
|
+
attachmentLayout: 'list',
|
|
28
|
+
attachments,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Handle action-based message extension (fetch task)
|
|
34
|
+
protected async handleTeamsMessagingExtensionFetchTask(
|
|
35
|
+
_context: TurnContext,
|
|
36
|
+
_action: MessagingExtensionAction
|
|
37
|
+
): Promise<TaskModuleResponse> {
|
|
38
|
+
return {
|
|
39
|
+
task: {
|
|
40
|
+
type: 'continue',
|
|
41
|
+
value: {
|
|
42
|
+
title: 'Create New Product',
|
|
43
|
+
height: 400,
|
|
44
|
+
width: 400,
|
|
45
|
+
card: CardFactory.adaptiveCard({
|
|
46
|
+
type: 'AdaptiveCard',
|
|
47
|
+
version: '1.4',
|
|
48
|
+
body: [
|
|
49
|
+
{ type: 'TextBlock', text: 'Create Product', weight: 'Bolder', size: 'Medium' },
|
|
50
|
+
{ type: 'Input.Text', id: 'name', placeholder: 'Product name', label: 'Name' },
|
|
51
|
+
{ type: 'Input.Text', id: 'description', placeholder: 'Description', label: 'Description', isMultiline: true },
|
|
52
|
+
{ type: 'Input.Number', id: 'price', placeholder: '0', label: 'Price ($)' },
|
|
53
|
+
],
|
|
54
|
+
actions: [{ type: 'Action.Submit', title: 'Create' }],
|
|
55
|
+
}),
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Handle action-based message extension (submit action)
|
|
62
|
+
protected async handleTeamsMessagingExtensionSubmitAction(
|
|
63
|
+
_context: TurnContext,
|
|
64
|
+
action: MessagingExtensionAction
|
|
65
|
+
): Promise<MessagingExtensionActionResponse> {
|
|
66
|
+
const data = action.data;
|
|
67
|
+
const product: IProduct = {
|
|
68
|
+
id: Date.now().toString(),
|
|
69
|
+
name: data.name || 'New Product',
|
|
70
|
+
description: data.description || '',
|
|
71
|
+
// Adaptive Card Input.Number submits its value as a string — coerce it.
|
|
72
|
+
price: Number(data.price) || 0,
|
|
73
|
+
category: 'New',
|
|
74
|
+
imageUrl: 'https://via.placeholder.com/150',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
composeExtension: {
|
|
79
|
+
type: 'result',
|
|
80
|
+
attachmentLayout: 'list',
|
|
81
|
+
attachments: [this.createProductCard(product)],
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Handle link unfurling
|
|
87
|
+
protected async handleTeamsAppBasedLinkQuery(
|
|
88
|
+
_context: TurnContext,
|
|
89
|
+
_query: { url: string }
|
|
90
|
+
): Promise<MessagingExtensionResponse> {
|
|
91
|
+
const product = mockProducts[0];
|
|
92
|
+
return {
|
|
93
|
+
composeExtension: {
|
|
94
|
+
type: 'result',
|
|
95
|
+
attachmentLayout: 'list',
|
|
96
|
+
attachments: [this.createProductCard(product)],
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private createProductCard(product: IProduct) {
|
|
102
|
+
const card = CardFactory.thumbnailCard(
|
|
103
|
+
product.name,
|
|
104
|
+
`$${product.price} | ${product.category}`,
|
|
105
|
+
[product.imageUrl],
|
|
106
|
+
[],
|
|
107
|
+
{ subtitle: product.description }
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const preview = CardFactory.thumbnailCard(product.name, product.description, [product.imageUrl]);
|
|
111
|
+
|
|
112
|
+
return { ...card, preview };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import express, { Request, Response } from 'express';
|
|
2
|
+
import { config, validateConfig } from './config';
|
|
3
|
+
import { createBotAdapter } from './adapters/botAdapter';
|
|
4
|
+
import { MessageExtensionBot } from './bot/MessageExtensionBot';
|
|
5
|
+
|
|
6
|
+
validateConfig();
|
|
7
|
+
|
|
8
|
+
// A message extension is invoked from the Teams compose box (search / action /
|
|
9
|
+
// link unfurling), not a console — so there is no --interactive mock loop here.
|
|
10
|
+
const app = express();
|
|
11
|
+
app.use(express.json());
|
|
12
|
+
|
|
13
|
+
const adapter = createBotAdapter();
|
|
14
|
+
const bot = new MessageExtensionBot();
|
|
15
|
+
|
|
16
|
+
// Health check endpoint (the deploy pipeline gates on this)
|
|
17
|
+
app.get('/health', (_req: Request, res: Response) => {
|
|
18
|
+
res.json({
|
|
19
|
+
status: 'healthy',
|
|
20
|
+
timestamp: new Date().toISOString(),
|
|
21
|
+
mockMode: config.mockMode,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Bot messaging endpoint — message-extension queries/actions/link-queries arrive here
|
|
26
|
+
app.post('/api/messages', async (req: Request, res: Response) => {
|
|
27
|
+
try {
|
|
28
|
+
await adapter.process(req, res, (context) => bot.run(context));
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error('Error processing message:', error);
|
|
31
|
+
res.status(500).send('Internal Server Error');
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
app.get('/', (_req: Request, res: Response) => {
|
|
36
|
+
res.json({
|
|
37
|
+
name: '{{projectName}}',
|
|
38
|
+
description: 'Microsoft Teams message extension (Bot Framework SDK v4)',
|
|
39
|
+
endpoints: { messaging: '/api/messages', health: '/health' },
|
|
40
|
+
mockMode: config.mockMode,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
app.listen(config.port, () => {
|
|
45
|
+
console.log(`\nMessage-extension server is running!`);
|
|
46
|
+
console.log(` Local: http://localhost:${config.port}`);
|
|
47
|
+
console.log(` Health: http://localhost:${config.port}/health`);
|
|
48
|
+
console.log(` Mode: ${config.mockMode ? 'Mock (development)' : 'Production'}`);
|
|
49
|
+
console.log(`\n Messaging endpoint: /api/messages`);
|
|
50
|
+
console.log(` Invoke it from the Teams compose box (search / action / link unfurl).`);
|
|
51
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface IProduct {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
price: number;
|
|
6
|
+
category: string;
|
|
7
|
+
imageUrl: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Sample data backing the search / action / link-unfurling responses. Swap this
|
|
11
|
+
// for a live Dataverse query (app-only token) per the teams-message-extension runbook.
|
|
12
|
+
export const mockProducts: IProduct[] = [
|
|
13
|
+
{ id: '1', name: 'Laptop Pro', description: 'High-performance laptop', price: 1299, category: 'Electronics', imageUrl: 'https://via.placeholder.com/150' },
|
|
14
|
+
{ id: '2', name: 'Wireless Mouse', description: 'Ergonomic wireless mouse', price: 49, category: 'Electronics', imageUrl: 'https://via.placeholder.com/150' },
|
|
15
|
+
{ id: '3', name: 'Mechanical Keyboard', description: 'RGB mechanical keyboard', price: 129, category: 'Electronics', imageUrl: 'https://via.placeholder.com/150' },
|
|
16
|
+
{ id: '4', name: 'USB-C Hub', description: '7-in-1 USB-C hub', price: 79, category: 'Electronics', imageUrl: 'https://via.placeholder.com/150' },
|
|
17
|
+
{ id: '5', name: 'Monitor Stand', description: 'Adjustable monitor stand', price: 89, category: 'Office', imageUrl: 'https://via.placeholder.com/150' },
|
|
18
|
+
{ id: '6', name: 'Desk Lamp', description: 'LED desk lamp', price: 45, category: 'Office', imageUrl: 'https://via.placeholder.com/150' },
|
|
19
|
+
{ id: '7', name: 'Webcam HD', description: '1080p webcam', price: 99, category: 'Electronics', imageUrl: 'https://via.placeholder.com/150' },
|
|
20
|
+
{ id: '8', name: 'Headphones', description: 'Noise-canceling headphones', price: 299, category: 'Electronics', imageUrl: 'https://via.placeholder.com/150' },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export function searchProducts(query: string): IProduct[] {
|
|
24
|
+
const q = query.toLowerCase();
|
|
25
|
+
return mockProducts.filter(p =>
|
|
26
|
+
p.name.toLowerCase().includes(q) ||
|
|
27
|
+
p.description.toLowerCase().includes(q) ||
|
|
28
|
+
p.category.toLowerCase().includes(q)
|
|
29
|
+
);
|
|
30
|
+
}
|