From be0072c9a02a2dec705d613b19f41a4e6cb28c78 Mon Sep 17 00:00:00 2001 From: Patrick Volum Date: Fri, 26 Mar 2021 10:27:04 -0400 Subject: [PATCH 01/12] Added Teams manifest type defenition and default value --- Composer/packages/client/src/constants.ts | 44 ++++++++++++++++- Composer/packages/types/src/creation.ts | 58 +++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/Composer/packages/client/src/constants.ts b/Composer/packages/client/src/constants.ts index 4b0ae7370c..7cd2079798 100644 --- a/Composer/packages/client/src/constants.ts +++ b/Composer/packages/client/src/constants.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { FeedName } from '@botframework-composer/types/src'; +import { FeedName, TeamsManifest, TeamsManifestObj } from '@botframework-composer/types/src'; import formatMessage from 'format-message'; import { IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown'; @@ -417,3 +417,45 @@ export const runtimeOptions: IDropdownOption[] = [ ]; export const onboardingDisabled = false; + +export const defaultTeamsManifest: TeamsManifest = { + $schema: 'https://developer.microsoft.com/en-us/json-schemas/teams/v1.9/MicrosoftTeams.schema.json', + manifestVersion: '1.9', + version: '1.0.0', + id: '{BOT_APPID}', + packageName: 'com.microsoft.yourcompany.{BOTNAME}', + developer: { + name: '', + websiteUrl: '', + privacyUrl: '', + termsOfUseUrl: '', + }, + icons: { + color: '', + outline: '', + }, + name: { + short: '{BOTNAME}', + full: '{BOTNAME} full name goes here.', + }, + description: { + short: 'Short description for {BOTNAME} goes here.', + full: 'Full description for {BOTNAME} goes here.', + }, + accentColor: '#781EFC', + bots: [ + { + botId: '{BOT_APPID}', + scopes: ['personal'], + supportsFiles: false, + isNotificationOnly: false, + }, + ], + permissions: ['identity', 'messageTeamMembers'], + validDomains: ['token.botframework.com'], + webApplicationInfo: { + id: '{BOT_APPID}', + resource: 'https://token.botframework.com/.auth/web/redirect', + }, + devicePermissions: ['notifications', 'openExternal'], +}; diff --git a/Composer/packages/types/src/creation.ts b/Composer/packages/types/src/creation.ts index 40216d36b2..892e62e315 100644 --- a/Composer/packages/types/src/creation.ts +++ b/Composer/packages/types/src/creation.ts @@ -6,3 +6,61 @@ export const nodeFeedKey = 'firstPartyNode'; export const defaultFeeds = [nodeFeedKey, csharpFeedKey] as const; export type FeedName = typeof defaultFeeds[number]; export type FeedType = 'npm' | 'nuget'; + +export type TeamsManifest = { + $schema: string; + manifestVersion: string; + version: string; + id: string; + packageName: string; + developer: Developer; + icons: Icons; + name: Name; + description: Name; + accentColor: string; + bots: Bot[]; + permissions: string[]; + validDomains: string[]; + webApplicationInfo: WebApplicationInfo; + devicePermissions: string[]; +}; + +type WebApplicationInfo = { + id: string; + resource: string; +}; + +type Bot = { + botId: string; + scopes: string[]; + commandList?: CommandList[]; + supportsFiles: boolean; + isNotificationOnly: boolean; +}; + +type CommandList = { + scopes: string[]; + commands: Command[]; +}; + +type Command = { + title: string; + description: string; +}; + +type Name = { + short: string; + full: string; +}; + +type Icons = { + color: string; + outline: string; +}; + +type Developer = { + name: string; + websiteUrl: string; + privacyUrl: string; + termsOfUseUrl: string; +}; From 04eb49fea5938765f8846e0d8d29690dda49f37b Mon Sep 17 00:00:00 2001 From: Patrick Volum Date: Fri, 26 Mar 2021 10:27:33 -0400 Subject: [PATCH 02/12] Added Teams manifest modal --- .../Adapters/TeamsManifestGenerator.tsx | 99 +++++++++++++++++++ .../pages/botProject/adapters/ABSChannels.tsx | 8 ++ 2 files changed, 107 insertions(+) create mode 100644 Composer/packages/client/src/components/Adapters/TeamsManifestGenerator.tsx diff --git a/Composer/packages/client/src/components/Adapters/TeamsManifestGenerator.tsx b/Composer/packages/client/src/components/Adapters/TeamsManifestGenerator.tsx new file mode 100644 index 0000000000..254bc14306 --- /dev/null +++ b/Composer/packages/client/src/components/Adapters/TeamsManifestGenerator.tsx @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** @jsx jsx */ +import { jsx } from '@emotion/core'; +import { DialogFooter } from 'office-ui-fabric-react/lib/Dialog'; +import { PrimaryButton } from 'office-ui-fabric-react/lib/Button'; +import formatMessage from 'format-message'; +import { Text } from 'office-ui-fabric-react/lib/Text'; +import { IconButton } from 'office-ui-fabric-react/lib/components/Button'; +import { FontSizes, NeutralColors } from '@uifabric/fluent-theme/lib/fluent'; +import { useRef } from 'react'; +import { ITextField, TextField } from 'office-ui-fabric-react/lib/components/TextField'; +import { DialogTypes, DialogWrapper } from '@bfc/ui-shared/lib/components/DialogWrapper'; + +import { defaultTeamsManifest } from '../../constants'; + +type TeamsManifestGeneratorProps = { + hidden: boolean; + onDismiss: () => void; +}; + +export const TeamsManifestGenerator = (props: TeamsManifestGeneratorProps) => { + const textFieldRef = useRef(null); + + const copyCodeToClipboard = () => { + try { + textFieldRef.current?.select; + textFieldRef.current?.select(); + document.execCommand('copy'); + textFieldRef.current?.setSelectionRange(0, 0); + textFieldRef.current?.blur(); + } catch (e) { + console.error('Something went wrong when trying to copy manifest content to clipboard.', e); + } + }; + + const generateTeamsManifest = () => { + return JSON.stringify(defaultTeamsManifest, null, 2); + }; + + return ( + +
+ {formatMessage('Teams manifest for your bot:')} + { + copyCodeToClipboard(); + }} + /> +
+ + + { + props.onDismiss(); + }} + /> + + +
+ ); +}; diff --git a/Composer/packages/client/src/pages/botProject/adapters/ABSChannels.tsx b/Composer/packages/client/src/pages/botProject/adapters/ABSChannels.tsx index 2c66d943f4..86766097ca 100644 --- a/Composer/packages/client/src/pages/botProject/adapters/ABSChannels.tsx +++ b/Composer/packages/client/src/pages/botProject/adapters/ABSChannels.tsx @@ -40,6 +40,7 @@ import { errorTextStyle, columnSizes, } from '../styles'; +import { TeamsManifestGenerator } from '../../../components/Adapters/TeamsManifestGenerator'; import ABSChannelSpeechModal from './ABSChannelSpeechModal'; @@ -92,6 +93,7 @@ export const ABSChannels: React.FC = (props) => { const [isLoading, setLoadingStatus] = useState(false); const [errorMessage, setErrorMessage] = useState(undefined); const [showSpeechModal, setShowSpeechModal] = useState(false); + const [showTeamsManifestModal, setShowTeamsManifestModal] = useState(true); const { setApplicationLevelError } = useRecoilValue(dispatcherState); /* Copied from Azure Publishing extension */ const getSubscriptions = async (token: string): Promise> => { @@ -581,6 +583,12 @@ export const ABSChannels: React.FC = (props) => { {absTableRow(CHANNELS.SPEECH, formatMessage('Speech'), speechHelpLink)} )} +