diff --git a/.vscode/settings.json b/.vscode/settings.json index 715d5b8f7a..e63df634d1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,13 @@ { - "cSpell.words": ["adal", "ipados", "teamspace", "uninitialize", "xvfb"], + "cSpell.words": ["adal", "frameless", "ipados", "teamsjs", "teamspace", "uninitialize", "xvfb"], "editor.defaultFormatter": "esbenp.prettier-vscode", + "eslint.workingDirectories": [ + "./apps/ssr-test-app/", + "./apps/teams-perf-test-app", + "./apps/teams-test-app/", + "./apps/typed-dependency-tester/", + "./packages/teams-js/" + ], "editor.formatOnSave": true, "editor.insertSpaces": true, "editor.tabSize": 2, diff --git a/apps/blazor-test-app/Blazor-Test-App.csproj b/apps/blazor-test-app/Blazor-Test-App.csproj index da88f8b16f..6477773d34 100644 --- a/apps/blazor-test-app/Blazor-Test-App.csproj +++ b/apps/blazor-test-app/Blazor-Test-App.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 enable diff --git a/apps/blazor-test-app/global.json b/apps/blazor-test-app/global.json index a4211ca730..b044d415e1 100644 --- a/apps/blazor-test-app/global.json +++ b/apps/blazor-test-app/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": ">=7.0.14" + "version": ">=8.0.4" } } diff --git a/apps/teams-test-app/index_cdn.html b/apps/teams-test-app/index_cdn.html index ac62c53460..546fd801b8 100644 --- a/apps/teams-test-app/index_cdn.html +++ b/apps/teams-test-app/index_cdn.html @@ -15,8 +15,8 @@
diff --git a/apps/teams-test-app/package.json b/apps/teams-test-app/package.json index 9a88578a48..6dee9e3418 100644 --- a/apps/teams-test-app/package.json +++ b/apps/teams-test-app/package.json @@ -3,14 +3,14 @@ "private": true, "author": "Microsoft Teams", "description": "Teams Test App utilizing Teams JavaScript client SDK to test Hosts", - "version": "2.26.0", + "version": "2.28.0", "scripts": { "build": "pnpm build:bundle", "build:bundle": "pnpm lint && webpack", "build:CDN": "pnpm lint && webpack --config webpack.cdn.config.js", "build:local": "pnpm lint && webpack --config webpack.local.config.js && pnpm copy", "clean": "rimraf ./build", - "copy": "shx cp ../../packages/teams-js/dist/MicrosoftTeams.min.js ./build/ && shx cp ../../packages/teams-js/dist/MicrosoftTeams.min.js.map ./build/", + "copy": "shx cp ../../packages/teams-js/dist/umd/MicrosoftTeams.min.js ./build/ && shx cp ../../packages/teams-js/dist/umd/MicrosoftTeams.min.js.map ./build/", "lint": "pnpm eslint ./src --max-warnings 0 --fix --ext .tsx", "start": "pnpm start:bundle", "start:bundle": "webpack serve", diff --git a/apps/teams-test-app/src/App.tsx b/apps/teams-test-app/src/App.tsx index 052b3815e5..21d2773f9d 100644 --- a/apps/teams-test-app/src/App.tsx +++ b/apps/teams-test-app/src/App.tsx @@ -6,7 +6,7 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { isTestBackCompat } from './components/utils/isTestBackCompat'; import { SecondRoute } from './pages/SecondRoute'; -import { TestApp } from './pages/TestApp'; +import { appInitializationTestQueryParameter, TestApp } from './pages/TestApp'; const urlParams = new URLSearchParams(window.location.search); @@ -29,7 +29,7 @@ if (!urlParams.has('customInit') || !urlParams.get('customInit')) { // we do it by adding appInitializationTest=true to query string if ( (urlParams.has('customInit') && urlParams.get('customInit')) || - (urlParams.has('appInitializationTest') && urlParams.get('appInitializationTest')) + (urlParams.has(appInitializationTestQueryParameter) && urlParams.get(appInitializationTestQueryParameter)) ) { console.info('Not calling appInitialization because part of App Initialization Test run'); } else { diff --git a/apps/teams-test-app/src/components/privateApis/ExternalAppCardActionsAPIs.tsx b/apps/teams-test-app/src/components/privateApis/ExternalAppCardActionsAPIs.tsx index e551bba154..4d1c6c3de3 100644 --- a/apps/teams-test-app/src/components/privateApis/ExternalAppCardActionsAPIs.tsx +++ b/apps/teams-test-app/src/components/privateApis/ExternalAppCardActionsAPIs.tsx @@ -1,4 +1,4 @@ -import { externalAppCardActions } from '@microsoft/teams-js'; +import { externalAppCardActions, IAdaptiveCardActionSubmit } from '@microsoft/teams-js'; import React from 'react'; import { ApiWithoutInput, ApiWithTextInput } from '../utils'; @@ -15,7 +15,7 @@ const CheckExternalAppCardActionsCapability = (): React.ReactElement => const ProcessActionSubmit = (): React.ReactElement => ApiWithTextInput<{ appId: string; - actionSubmitPayload: externalAppCardActions.IAdaptiveCardActionSubmit; + actionSubmitPayload: IAdaptiveCardActionSubmit; }>({ name: 'processActionSubmit', title: 'Process Action Submit', diff --git a/apps/teams-test-app/src/components/privateApis/ExternalAppCardActionsForCEAAPIs.tsx b/apps/teams-test-app/src/components/privateApis/ExternalAppCardActionsForCEAAPIs.tsx new file mode 100644 index 0000000000..282fc84f7f --- /dev/null +++ b/apps/teams-test-app/src/components/privateApis/ExternalAppCardActionsForCEAAPIs.tsx @@ -0,0 +1,92 @@ +import { AppId, externalAppCardActionsForCEA, IAdaptiveCardActionSubmit } from '@microsoft/teams-js'; +import React from 'react'; + +import { ApiWithoutInput, ApiWithTextInput } from '../utils'; +import { ModuleWrapper } from '../utils/ModuleWrapper'; + +const CheckExternalAppCardActionsForCEACapability = (): React.ReactElement => + ApiWithoutInput({ + name: 'checkExternalAppCardActionsForCEACapability', + title: 'Check External App Card Actions For CEA Capability', + onClick: async () => + `External App Card Actions For CEA module ${ + externalAppCardActionsForCEA.isSupported() ? 'is' : 'is not' + } supported`, + }); + +const CECProcessActionSubmit = (): React.ReactElement => + ApiWithTextInput<{ + appId: AppId; + conversationId: string; + actionSubmitPayload: IAdaptiveCardActionSubmit; + }>({ + name: 'processActionSubmitForCEA', + title: 'Process Action Submit For CEA', + onClick: { + validateInput: (input) => { + if (!input.appId) { + throw new Error('appId is required'); + } + if (!input.actionSubmitPayload) { + throw new Error('actionSubmitPayload is required'); + } + }, + submit: async (input) => { + await externalAppCardActionsForCEA.processActionSubmit( + input.appId, + input.conversationId, + input.actionSubmitPayload, + ); + return 'Completed'; + }, + }, + defaultInput: JSON.stringify({ + appId: 'b7f8c0a0-6c1d-4a9a-9c0a-2c3f1c0a3b0a', + actionSubmitPayload: { + id: 'submitId', + data: 'data1', + }, + }), + }); + +const CECProcessActionOpenUrl = (): React.ReactElement => + ApiWithTextInput<{ + appId: AppId; + conversationId: string; + url: string; + }>({ + name: 'processActionOpenUrlForCEA', + title: 'Process Action Open Url For CEA', + onClick: { + validateInput: (input) => { + if (!input.appId) { + throw new Error('appId is required'); + } + if (!input.url) { + throw new Error('url is required'); + } + }, + submit: async (input) => { + const result = await externalAppCardActionsForCEA.processActionOpenUrl( + input.appId, + input.conversationId, + new URL(input.url), + ); + return JSON.stringify(result); + }, + }, + defaultInput: JSON.stringify({ + appId: 'b7f8c0a0-6c1d-4a9a-9c0a-2c3f1c0a3b0a', + url: 'https://www.example.com', + }), + }); + +const ExternalAppCardActionsForCEAAPIs = (): React.ReactElement => ( + + + + + +); + +export default ExternalAppCardActionsForCEAAPIs; diff --git a/apps/teams-test-app/src/pages/TestApp.tsx b/apps/teams-test-app/src/pages/TestApp.tsx index 421c8faa8c..f8264834ae 100644 --- a/apps/teams-test-app/src/pages/TestApp.tsx +++ b/apps/teams-test-app/src/pages/TestApp.tsx @@ -41,6 +41,7 @@ import ChatAPIs from '../components/privateApis/ChatAPIs'; import CopilotAPIs from '../components/privateApis/CopilotAPIs'; import ExternalAppAuthenticationAPIs from '../components/privateApis/ExternalAppAuthenticationAPIs'; import ExternalAppCardActionsAPIs from '../components/privateApis/ExternalAppCardActionsAPIs'; +import ExternalAppCardActionsForCEAAPIs from '../components/privateApis/ExternalAppCardActionsForCEAAPIs'; import ExternalAppCommandsAPIs from '../components/privateApis/ExternalAppCommandsAPIs'; import FilesAPIs from '../components/privateApis/FilesAPIs'; import FullTrustAPIs from '../components/privateApis/FullTrustAPIs'; @@ -66,12 +67,32 @@ import VideoAPIs from '../components/VideoEffectsApis'; import VisualMediaAPIs from '../components/VisualMediaAPIs'; import WebStorageAPIs from '../components/WebStorageAPIs'; +export const appInitializationTestQueryParameter = 'appInitializationTest'; + export const TestApp: React.FC = () => { const dialogWindowRef = React.useRef(null); + const [iframeUrl, setIframeUrl] = React.useState(null); + + const loadCurrentUrl = (): void => { + setIframeUrl(new URL(window.location.href + `?${appInitializationTestQueryParameter}=true`)); + }; return ( <> + +
+ {iframeUrl !== null && ( +
+ IFRAME:

+ {/*eslint-disable-next-line @microsoft/sdl/react-iframe-missing-sandbox -- always use the sandbox attribute, but this is a test app and we fully control the content going into it, so it's okay not to here. */} +