Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] Add store.openStoreExperience and otherApp.notifyAppInstall for BizChat in context store #2569

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion apps/teams-test-app/src/components/OtherAppStateChangeAPIs.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { otherAppStateChange } from '@microsoft/teams-js';
import { AppId, otherAppStateChange } from '@microsoft/teams-js';
import React, { ReactElement } from 'react';

import { ApiWithoutInput } from './utils';
Expand Down Expand Up @@ -39,12 +39,23 @@ const UnregisterAppInstallHandler = (): React.ReactElement =>
},
});

const NotifyAppInstallHandler = (): React.ReactElement =>
ApiWithoutInput({
name: 'otherAppStateChange_notifyAppInstall',
title: 'Notify App Install',
onClick: async () => {
otherAppStateChange.notifyAppInstall([new AppId('12345')]);
return 'notified';
},
});

const OtherAppStateChangedAPIs = (): ReactElement => (
<>
<ModuleWrapper title="OtherAppStateChanged">
<CheckOtherAppStateChangeCapability />
<RegisterAppInstallHandler />
<UnregisterAppInstallHandler />
<NotifyAppInstallHandler />
</ModuleWrapper>
</>
);
Expand Down
39 changes: 39 additions & 0 deletions apps/teams-test-app/src/components/StoreAPIs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { store } from '@microsoft/teams-js';
import React, { ReactElement } from 'react';

import { ApiWithoutInput } from './utils';
import { ModuleWrapper } from './utils/ModuleWrapper';

const CheckStoreCapability = (): React.ReactElement =>
ApiWithoutInput({
name: 'store_isSupported',
title: 'Check Store Capability',
onClick: async () => `Store module ${store.isSupported() ? 'is' : 'is not'} supported`,
});

const OpenStoreExperienceHandler = (): React.ReactElement =>
ApiWithoutInput({
name: 'store.openStoreExperience',
title: 'Open Store',
onClick: async () => {
const params = {
appId: '1234',
dialogType: store.dialogType.ICS,
supportedApps: [],
userHasCopilotLicense: true,
};
await store.openStoreExperience(params);
return 'opened';
},
});

const StoredAPIs = (): ReactElement => (
<>
<ModuleWrapper title="Store">
<CheckStoreCapability />
<OpenStoreExperienceHandler />
</ModuleWrapper>
</>
);

export default StoredAPIs;
2 changes: 2 additions & 0 deletions apps/teams-test-app/src/pages/TestApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import SecondaryBrowserAPIs from '../components/SecondaryBrowserAPIs';
import SharingAPIs from '../components/SharingAPIs';
import StageViewAPIs from '../components/StageViewAPIs';
import StageViewSelfAPIs from '../components/StageViewSelfAPIs';
import StoreAPIs from '../components/StoreAPIs';
import TeamsCoreAPIs from '../components/TeamsCoreAPIs';
import ThirdPartyCloudStorageAPIs from '../components/ThirdPartyCloudStorageAPIs';
import CookieAccessComponent from '../components/ThirdPatryCookies';
Expand Down Expand Up @@ -157,6 +158,7 @@ export const TestApp: React.FC = () => {
{ name: 'WebStorageAPIs', component: <WebStorageAPIs /> },
{ name: 'StageViewAPIs', component: <StageViewAPIs /> },
{ name: 'StageViewSelfAPIs', component: <StageViewSelfAPIs /> },
{ name: 'StoreAPIs', component: <StoreAPIs /> },
{ name: 'TeamsCoreAPIs', component: <TeamsCoreAPIs /> },
{ name: 'TeamsAPIs', component: <TeamsAPIs /> },
{ name: 'ThirdPartyCloudStorageAPIs', component: <ThirdPartyCloudStorageAPIs /> },
Expand Down
3 changes: 3 additions & 0 deletions packages/teams-js/src/internal/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export const enum ApiName {
Navigation_ReturnFocus = 'navigation.returnFocus',
Notifications_ShowNotification = 'notifications.showNotification',
OtherAppStateChange_Install = 'otherApp.install',
OtherAppStateChange_NotifyAppInstall = 'otherApp.notifyAppInstall',
OtherAppStateChange_UnregisterInstall = 'otherApp.unregisterInstall',
Pages_AppButton_OnClick = 'pages.appButton.onClick',
Pages_AppButton_OnHoverEnter = 'pages.appButton.onHoverEnter',
Expand Down Expand Up @@ -322,6 +323,8 @@ export const enum ApiName {
Sharing_ShareWebContent = 'sharing.shareWebContent',
StageView_Open = 'stageView.open',
StageView_Self_Close = 'stageView.self.close',
Store_OpenStoreExperience = 'store.openStoreExperience',
Store_RegisterMessageForChildHandler = 'store.registerMessageForChildHandler',
Tasks_StartTask = 'tasks.startTask',
Tasks_SubmitTask = 'tasks.submitTask',
Tasks_UpdateTask = 'tasks.updateTask',
Expand Down
1 change: 1 addition & 0 deletions packages/teams-js/src/private/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ export { appEntity } from './appEntity';
export { teams } from './teams';
export { videoEffectsEx } from './videoEffectsEx';
export { hostEntity } from './hostEntity';
export { store } from './store';
25 changes: 25 additions & 0 deletions packages/teams-js/src/private/otherAppStateChange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { registerHandler, removeHandler } from '../internal/handlers';
import { ensureInitialized } from '../internal/internalAPIs';
import { ApiName, ApiVersionNumber, getApiVersionTag } from '../internal/telemetry';
import { isNullOrUndefined } from '../internal/typeCheckUtilities';
import { AppId } from '../public/appId';
import { ErrorCode } from '../public/interfaces';
import { runtime } from '../public/runtime';

Expand Down Expand Up @@ -111,6 +112,30 @@ export namespace otherAppStateChange {
removeHandler(ApiName.OtherAppStateChange_Install);
}

/**
* @hidden
* @beta
* @internal
* Limited to Microsoft-internal use
*
* This function should be called by the Store App to notify the host that the
* app with the given appId has been installed.
*
* @throws Error if {@link app.initialize} has not successfully completed or if the platform
* does not support the otherAppStateChange capability.
*/
export function notifyAppInstall(appId: AppId): void {
if (!isSupported()) {
throw new Error(ErrorCode.NOT_SUPPORTED_ON_PLATFORM.toString());
}

sendMessageToParent(
getApiVersionTag(otherAppStateChangeTelemetryVersionNumber, ApiName.OtherAppStateChange_NotifyAppInstall),
ApiName.OtherAppStateChange_NotifyAppInstall,
[appId.toString()],
);
}

/**
* Checks if the otherAppStateChange capability is supported by the host
* @returns boolean to represent whether the otherAppStateChange capability is supported
Expand Down
61 changes: 61 additions & 0 deletions packages/teams-js/src/private/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { sendMessageToParent } from '../internal/communication';
import { ensureInitialized } from '../internal/internalAPIs';
import { ApiName, ApiVersionNumber, getApiVersionTag } from '../internal/telemetry';
import { ErrorCode } from '../public/interfaces';
import { runtime } from '../public/runtime';

/**
* v2 APIs telemetry file: All of APIs in this capability file should send out API version v2 ONLY
*/
const storeTelemetryVersionNumber: ApiVersionNumber = ApiVersionNumber.V_2;

/**
* In context store.
*
* This functionality is in Beta.
* @beta
*/
export namespace store {
/** Represents set of parameters needed to open the appInstallDialog. */
export interface OpenStoreParams {
/** A unique identifier for the app being installed. */
appId: string;
dialogType: dialogType;
supportedApps: string[];
userHasCopilotLicense: boolean;
}

export enum dialogType {
fullStore = 'fullStore',
ICS = 'ICS',
appDetails = 'appDetails',
}

/**
* Displays different forms of Store or App Install Dialogs based on the dialogType.
* Promise is returned once Store App initialization is completed.
*/
export function openStoreExperience(openStoreParams: OpenStoreParams): void {
console.log({ openStoreExperience: openStoreParams });
if (!isSupported()) {
throw new Error(ErrorCode.NOT_SUPPORTED_ON_PLATFORM.toString());
}

console.log('send message');
sendMessageToParent(
getApiVersionTag(storeTelemetryVersionNumber, ApiName.Store_OpenStoreExperience),
ApiName.Store_OpenStoreExperience,
[openStoreParams],
);
}

/**
* Checks if the store capability is supported by the host.
* @returns boolean to represent whether the store capability is supported.
*
* @throws Error if {@linkcode app.initialize} has not successfully completed
*/
export function isSupported(): boolean {
return ensureInitialized(runtime) && !!runtime.supports.store;
}
}
1 change: 1 addition & 0 deletions packages/teams-js/src/public/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ interface IRuntimeV4 extends IBaseRuntime {
readonly stageView?: {
readonly self?: {};
};
readonly store?: {};
readonly teams?: {
readonly fullTrust?: {
readonly joinedTeams?: {};
Expand Down
Loading