This repository was archived by the owner on Jul 9, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 376
feat: Add runtime settings page and eject #2572
Merged
Merged
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
22a309f
add new runtime settings page
benbrown 93383a0
add popup modal for pickign runtime
benbrown 68b9952
add ability for plugins to specify a runtime template
benbrown 222d8c7
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown fbac756
add sample runtime to localPublish
benbrown 4b4fb58
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 7cbb723
handle success and failure of runtime injection
benbrown 04bd2bd
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 9b3f89a
respect enableCustomRuntime
benbrown f9ed942
pull real runtime code
benbrown 4e7437b
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown d921a9a
eject real code
benbrown fb6ccbb
change the path of the declarative assets relative to the runtime
benbrown ab9cba4
update code copying to reflect new asset locations
benbrown 6ca6d2f
cleanup
benbrown 6a3861c
allow parameters to be included in start command
benbrown 870bd50
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 13e91fa
update readme with new info about additional plugin APIs
benbrown b03c870
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown d4cb3f5
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 53038a5
change schema of settings
benbrown f34164f
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown c1cbee3
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 9280318
little bit more error correction
benbrown 3bbdd6b
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 3e5fd1d
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 1a0eb8e
fix issue with field binding
benbrown 164c946
Merge branch 'master' into benbrown/2470
benbrown 20bef08
Merge branch 'master' into benbrown/2470
benbrown c78bed0
Merge branch 'master' into benbrown/2470
benbrown 16cf4d9
fix form behaviors
benbrown f49acfa
Merge branch 'benbrown/2470' of github.com:microsoft/BotFramework-Com…
benbrown dbcef7c
Merge branch 'master' into benbrown/2470
cwhitten 7b03572
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown 078cd1b
address comments from andy
benbrown 7b0581e
Merge branch 'master' of github.com:microsoft/BotFramework-Composer i…
benbrown File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,44 @@ | ||
| ## Bot Project | ||
| ## Bot Runtime | ||
| Bot project is the launcher project for the bots written in declarative form (JSON), using the Composer, for the Bot Framework SDK. | ||
| This same code is used by Composer to start the bot locally for testing. | ||
|
|
||
| ## Instructions for setting up the Bot Project runtime | ||
| The Bot Project is a regular Bot Framework SDK V4 project. Before you can launch it from the emulator, you need to make sure you can run the bot. | ||
| ## Instructions for using and customizing the bot runtime | ||
|
|
||
| Composer can be configured to use a customized copy of this runtime. | ||
| A copy of it can be added to your project automatically by using the "runtime settings" page in Composer. | ||
|
|
||
| The Bot Project is a regular Bot Framework SDK V4 project. You can modify the code of this project | ||
| and continue to use it with Composer. | ||
|
|
||
| * Add additional middleware | ||
| * Customize the state storage system | ||
| * Add custom dialog classes | ||
|
|
||
| ### Prerequisite: | ||
| * Install .Netcore 3.1 | ||
|
|
||
| ### Commands: | ||
| ### Build: | ||
|
|
||
| * from root folder | ||
| * cd BotProject | ||
| * cd Templates/CSharp | ||
| * cd [my bot folder]/runtime | ||
| * dotnet user-secrets init // init the user secret id | ||
| * dotnet build // build | ||
|
|
||
|
|
||
| ### Run from Command line: | ||
| * cd [my bot folder]/runtime | ||
| * dotnet run // start the bot | ||
| * It will start a web server and listening at http://localhost:3979. | ||
|
|
||
| ### Run with Composer | ||
|
|
||
| Open your bot project in Composer. Navigate to the runtime settings tab. | ||
|
|
||
| Set the path to runtime to the full path to your runtime code. Customize the start command as necessary. | ||
|
|
||
| The "Start Bot" button will now use your customized runtime. | ||
|
|
||
| Note: the application code must be built and ready to run before Composer can manage it. | ||
|
|
||
| ### Test bot | ||
| * You can set you emulator to connect to http://localhost:3979/api/messages. | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
Composer/packages/client/src/pages/setting/runtime-settings/ejectModal.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
| /** @jsx jsx */ | ||
| import { jsx } from '@emotion/core'; | ||
| import { useEffect, useMemo, useState, useContext } from 'react'; | ||
| import { Dialog, DialogType } from 'office-ui-fabric-react/lib/Dialog'; | ||
| import formatMessage from 'format-message'; | ||
| import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'; | ||
| import { DialogFooter } from 'office-ui-fabric-react/lib/Dialog'; | ||
| import { ChoiceGroup, IChoiceGroupOption } from 'office-ui-fabric-react/lib/ChoiceGroup'; | ||
|
|
||
| import { StoreContext } from '../../../store'; | ||
|
|
||
| import { modalControlGroup } from './style'; | ||
|
|
||
| export interface EjectModalProps { | ||
| ejectRuntime: (templateKey: string) => void; | ||
| hidden: boolean; | ||
| closeModal: () => void; | ||
| } | ||
|
|
||
| export const EjectModal: React.FC<EjectModalProps> = props => { | ||
| const [selectedTemplate, setSelectedTemplate] = useState<string | undefined>(); | ||
| const { state, actions } = useContext(StoreContext); | ||
| const { runtimeTemplates } = state; | ||
|
|
||
| useEffect(() => { | ||
| actions.getRuntimeTemplates(); | ||
| }, []); | ||
|
|
||
| const availableRuntimeTemplates = useMemo(() => { | ||
| return runtimeTemplates.map(t => { | ||
| return { | ||
| text: t.name, | ||
| key: t.key, | ||
| }; | ||
| }); | ||
| }, [runtimeTemplates]); | ||
|
|
||
| const selectTemplate = (ev, item?: IChoiceGroupOption) => { | ||
| if (item) { | ||
| setSelectedTemplate(item.key); | ||
| } | ||
| }; | ||
|
|
||
| const doEject = () => { | ||
| if (selectedTemplate) { | ||
| props.ejectRuntime(selectedTemplate); | ||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <Dialog | ||
| hidden={props.hidden} | ||
| onDismiss={props.closeModal} | ||
| dialogContentProps={{ | ||
| type: DialogType.normal, | ||
| title: formatMessage('Add custom runtime'), | ||
| subText: formatMessage('Select runtime version to add'), | ||
| }} | ||
| modalProps={{ | ||
| isBlocking: false, | ||
| }} | ||
| > | ||
| <div css={modalControlGroup}> | ||
| <ChoiceGroup options={availableRuntimeTemplates} onChange={selectTemplate} required={true} /> | ||
| </div> | ||
| <DialogFooter> | ||
| <DefaultButton onClick={props.closeModal}>Cancel</DefaultButton> | ||
benbrown marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <PrimaryButton onClick={doEject} disabled={!selectedTemplate}> | ||
| {formatMessage('Okay')} | ||
| </PrimaryButton> | ||
| </DialogFooter> | ||
| </Dialog> | ||
| ); | ||
| }; | ||
123 changes: 123 additions & 0 deletions
123
Composer/packages/client/src/pages/setting/runtime-settings/index.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| /** @jsx jsx */ | ||
| import { jsx } from '@emotion/core'; | ||
| import { useState, useContext } from 'react'; | ||
| import formatMessage from 'format-message'; | ||
| import { Toggle } from 'office-ui-fabric-react/lib/Toggle'; | ||
| import { TextField } from 'office-ui-fabric-react/lib/TextField'; | ||
| import { Link } from 'office-ui-fabric-react/lib/Link'; | ||
| import { RouteComponentProps } from '@reach/router'; | ||
|
|
||
| import { LoadingSpinner } from '../../../components/LoadingSpinner'; | ||
| import { StoreContext } from '../../../store'; | ||
|
|
||
| import { EjectModal } from './ejectModal'; | ||
| import { | ||
| breathingSpace, | ||
| runtimeSettingsStyle, | ||
| runtimeControls, | ||
| runtimeControlsTitle, | ||
| runtimeToggle, | ||
| controlGroup, | ||
| } from './style'; | ||
|
|
||
| export const RuntimeSettings: React.FC<RouteComponentProps> = () => { | ||
| const { state, actions } = useContext(StoreContext); | ||
| const { botName, settings, projectId } = state; | ||
| const [formDataErrors, setFormDataErrors] = useState({ command: '', path: '' }); | ||
| const [ejectModalVisible, setEjectModalVisible] = useState(false); | ||
|
|
||
| const changeEnabled = (_, on) => { | ||
| actions.setSettings(projectId, botName, { ...settings, runtime: { ...settings.runtime, customRuntime: on } }); | ||
benbrown marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| const updateSetting = field => (e, newValue) => { | ||
| let valid = true; | ||
| let error = 'There was an error'; | ||
| if (newValue === '') { | ||
| valid = false; | ||
| error = 'This is a required field.'; | ||
| } | ||
|
|
||
| actions.setSettings(projectId, botName, { ...settings, runtime: { ...settings.runtime, [field]: newValue } }); | ||
|
|
||
| if (valid) { | ||
| setFormDataErrors({ ...formDataErrors, [field]: '' }); | ||
| } else { | ||
| setFormDataErrors({ ...formDataErrors, [field]: error }); | ||
| } | ||
| }; | ||
|
|
||
| const header = () => ( | ||
| <div css={runtimeControls}> | ||
| <h1 css={runtimeControlsTitle}>{formatMessage('Bot runtime settings')}</h1> | ||
| <p>{formatMessage('Configure Composer to start your bot using runtime code you can customize and control.')}</p> | ||
| </div> | ||
| ); | ||
|
|
||
| const toggle = () => ( | ||
| <div css={runtimeToggle}> | ||
| <Toggle | ||
| label={formatMessage('Use custom runtime')} | ||
| inlineLabel | ||
| onChange={changeEnabled} | ||
| checked={settings.runtime && settings.runtime.customRuntime === true} | ||
| /> | ||
| </div> | ||
| ); | ||
|
|
||
| const showEjectModal = () => { | ||
| setEjectModalVisible(true); | ||
| }; | ||
| const closeEjectModal = () => { | ||
| setEjectModalVisible(false); | ||
| }; | ||
|
|
||
| const ejectRuntime = async (templateKey: string) => { | ||
| await actions.ejectRuntime(projectId, templateKey); | ||
| closeEjectModal(); | ||
| }; | ||
|
|
||
| return botName ? ( | ||
| <div css={runtimeSettingsStyle}> | ||
| {header()} | ||
| {toggle()} | ||
| <div css={controlGroup}> | ||
| <TextField | ||
| label={formatMessage('Runtime code location')} | ||
| value={settings.runtime ? settings.runtime.path : ''} | ||
| styles={name} | ||
| required | ||
| onChange={updateSetting('path')} | ||
| errorMessage={formDataErrors.path} | ||
| data-testid="runtimeCodeLocation" | ||
| disabled={!settings.runtime || !settings.runtime.customRuntime} | ||
| /> | ||
| {formatMessage('Or: ')} | ||
| <Link | ||
| onClick={showEjectModal} | ||
| disabled={!settings.runtime || !settings.runtime.customRuntime} | ||
| css={breathingSpace} | ||
| > | ||
| {formatMessage('Get a new copy of the runtime code')} | ||
| </Link> | ||
|
|
||
| <TextField | ||
| label={formatMessage('Start command')} | ||
| value={settings.runtime ? settings.runtime.command : ''} | ||
| styles={name} | ||
| required | ||
| onChange={updateSetting('command')} | ||
| errorMessage={formDataErrors.command} | ||
| data-testid="runtimeCommand" | ||
| disabled={!settings.runtime || !settings.runtime.customRuntime} | ||
| /> | ||
| </div> | ||
| <EjectModal hidden={!ejectModalVisible} closeModal={closeEjectModal} ejectRuntime={ejectRuntime} /> | ||
| </div> | ||
| ) : ( | ||
| <LoadingSpinner /> | ||
| ); | ||
| }; | ||
51 changes: 51 additions & 0 deletions
51
Composer/packages/client/src/pages/setting/runtime-settings/style.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| import { css } from '@emotion/core'; | ||
| import { FontWeights, FontSizes } from 'office-ui-fabric-react/lib/Styling'; | ||
| export const runtimeSettingsStyle = css` | ||
| position: absolute; | ||
| top: 0; | ||
| bottom: 0; | ||
| left: 0; | ||
| right: 0; | ||
| padding: 1rem; | ||
| display: flex; | ||
| flex-direction: column; | ||
| box-sizing: border-box; | ||
| `; | ||
|
|
||
| export const runtimeControls = css` | ||
| margin-bottom: 18px; | ||
|
|
||
| & > h1 { | ||
| margin-top: 0; | ||
| } | ||
| `; | ||
|
|
||
| export const runtimeToggle = css` | ||
| display: flex; | ||
|
|
||
| & > * { | ||
| margin-right: 2rem; | ||
| } | ||
| `; | ||
|
|
||
| export const controlGroup = css` | ||
| border: 1px solid rgb(237, 235, 233); | ||
| padding: 0.5rem 1rem 1rem 1rem; | ||
| `; | ||
|
|
||
| export const modalControlGroup = css` | ||
| border: 1px solid rgb(237, 235, 233); | ||
| padding: 0.5rem 1rem 1rem 1rem; | ||
| `; | ||
|
|
||
| export const runtimeControlsTitle = css` | ||
| font-size: ${FontSizes.xLarge}; | ||
| font-weight: ${FontWeights.semibold}; | ||
| `; | ||
|
|
||
| export const breathingSpace = css` | ||
| margin-bottom: 1rem; | ||
| `; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.