Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e9d070b
release: 1.4.0-rc0
cwhitten Mar 13, 2021
86b92bf
fix: lg create error with multi-language (#6412)
lei9444 Mar 15, 2021
44ca903
fix: Remove Attachment Lg template when they are deleted in the Respo…
tdurnford Mar 13, 2021
3228d97
1.4.0-rc1
cwhitten Mar 15, 2021
7d4b2bd
Added gray Composer icon to 'no triggers' dialog state (#6414)
tonyanziano Mar 15, 2021
413a4ff
Get an ARM token only when publishing to Azure (#6418)
tonyanziano Mar 16, 2021
17c2f7d
fix: composer doesn't see component dialogs that are in subfolders (#…
lei9444 Mar 16, 2021
e40f9bf
fix: revert yeoman-environment to 2.10.3 from 3.1.0 (#6415)
benbrown Mar 16, 2021
8c279bc
1.4.0-rc2
cwhitten Mar 16, 2021
f80790d
fix: load feature flags if default keys have changed (#6432)
a-b-r-o-w-n Mar 16, 2021
48c822e
fix: use new create flow during add skill if enabled (#6427)
pavolum Mar 16, 2021
8f47bf1
Update bf-orchestrator to 4.12.0-beta.20210316.cdd0819 (#6435)
taicchoumsft Mar 16, 2021
cd026f8
fix: make CSS show triangles in project tree (#6428)
beyackle Mar 16, 2021
c40ecb0
feat: Implement layout to errorCallout (#6396)
cdonke Mar 16, 2021
3ae8aaa
fis: change feature flag text (#6438)
pavolum Mar 17, 2021
8a115bc
feat: update runtime package to 4.12.1 (#6441)
boydc2014 Mar 17, 2021
ffda715
fix: hidden showCode button when url is all & show code for form dial…
alanlong9278 Mar 17, 2021
830559e
Fixing projectId state by ordering state change (#6437)
pavolum Mar 17, 2021
d2cb11b
prepare changelog for 1.4.0
a-b-r-o-w-n Mar 17, 2021
82a36c4
1.4.0-rc3
boydc2014 Mar 18, 2021
7a9d518
feat: take 4.12.2 runtime package (#6469)
boydc2014 Mar 18, 2021
1bcd96b
fix: Allow multiline variations for LG text and speech modalities (#6…
hatpick Mar 15, 2021
d5a04ac
fix actions (#6476)
hatpick Mar 18, 2021
ce64aef
release: 1.4.0
cwhitten Mar 18, 2021
501336b
Update 1.4.0.md
cwhitten Mar 18, 2021
2d7d9d1
RC4
cwhitten Mar 22, 2021
0b0a126
Update bf-orchestrator to 4.12.0-beta.20210322.314475a (#6496)
taicchoumsft Mar 22, 2021
a7ceff8
Merge branch '1.4.0-rc4' of https://github.com/microsoft/BotFramework…
cwhitten Mar 22, 2021
223388e
Merge branch '1.4.0' of https://github.com/microsoft/BotFramework-Com…
cwhitten Mar 22, 2021
8f1694a
fix: unify runtime path from ejecting (#6520)
lei9444 Mar 24, 2021
037e7a7
1.4.1
cwhitten Mar 31, 2021
6e75a0a
Adds 1.4.1 version
cwhitten Mar 31, 2021
d062a1c
1.4.1 release notes
cwhitten Mar 31, 2021
27b2bfa
Publish page now populates publish types (#6544)
GeoffCoxMSFT Mar 25, 2021
c73176a
Update CHANGELOG
cwhitten Mar 31, 2021
d938ee7
ARM token for provisioning is now passed via body. (#6684)
tonyanziano Apr 5, 2021
bcf87f0
Update readme
cwhitten Apr 5, 2021
d167636
fix: added telemetry support to node runtime and adopted missing midd…
chon219 Mar 30, 2021
dcde81b
add retry logic for adding app password (#6703)
Apr 6, 2021
a7e5780
Update README.md
cwhitten Apr 6, 2021
75ffa8e
feat: Breaking change upgrade UX from 1.4 to 2.0 (#7388)
srinaath May 4, 2021
8eb5eb2
Merge branch '1.4.1' of https://github.com/microsoft/BotFramework-Com…
May 6, 2021
44f26f6
Updated migration aka.ms link
May 6, 2021
251b945
Merge branch 'main' into chore/1.4.1-rebase
srinaath May 6, 2021
0c8b819
Revert "Updated migration aka.ms link"
May 6, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import { useRecoilValue } from 'recoil';
import { SharedColors, NeutralColors } from '@uifabric/fluent-theme';
import { IpcRendererEvent } from 'electron';

import { AppUpdaterStatus } from '../constants';
import { appUpdateState, dispatcherState } from '../recoilModel';
import { AppUpdaterStatus } from '../../constants';
import { appUpdateState, dispatcherState } from '../../recoilModel';

import { breakingUpdatesMap } from './breakingUpdates/breakingUpdatesMap';

const updateAvailableDismissBtn: Partial<IButtonStyles> = {
root: {
Expand Down Expand Up @@ -85,6 +87,12 @@ const downloadOptions = {
installAndUpdate: 'installAndUpdate',
};

// TODO: factor this out into shared or types
type BreakingUpdateMetaData = {
explicitCheck: boolean;
uxId: string;
};

// -------------------- AppUpdater -------------------- //

export const AppUpdater: React.FC<{}> = () => {
Expand All @@ -93,9 +101,11 @@ export const AppUpdater: React.FC<{}> = () => {
);
const { downloadSizeInBytes, error, progressPercent, showing, status, version } = useRecoilValue(appUpdateState);
const [downloadOption, setDownloadOption] = useState(downloadOptions.installAndUpdate);
const [breakingMetaData, setBreakingMetaData] = useState<BreakingUpdateMetaData | undefined>(undefined);

const handleDismiss = useCallback(() => {
setAppUpdateShowing(false);
setBreakingMetaData(undefined);
if (status === AppUpdaterStatus.UPDATE_UNAVAILABLE || status === AppUpdaterStatus.UPDATE_FAILED) {
setAppUpdateStatus(AppUpdaterStatus.IDLE, undefined);
}
Expand All @@ -118,53 +128,69 @@ export const AppUpdater: React.FC<{}> = () => {
setDownloadOption(option);
}, []);

// necessary?
const handleContinueFromBreakingUx = useCallback(() => {
handlePreDownloadOkay();
}, [handlePreDownloadOkay]);

// listen for app updater events from main process
useEffect(() => {
ipcRenderer.on('app-update', (_event: IpcRendererEvent, name: string, payload) => {
switch (name) {
case 'update-available':
setAppUpdateStatus(AppUpdaterStatus.UPDATE_AVAILABLE, payload.version);
setAppUpdateShowing(true);
break;

case 'progress': {
const progress = +(payload.percent as number).toFixed(2);
setAppUpdateProgress(progress, payload.total);
break;
}
ipcRenderer.on(
'app-update',
(_event: IpcRendererEvent, name: string, payload, breakingMetaData?: BreakingUpdateMetaData) => {
switch (name) {
case 'update-available':
setAppUpdateStatus(AppUpdaterStatus.UPDATE_AVAILABLE, payload.version);
setAppUpdateShowing(true);
break;

case 'update-in-progress': {
setAppUpdateStatus(AppUpdaterStatus.UPDATE_AVAILABLE, payload.version);
setAppUpdateShowing(true);
break;
}
case 'progress': {
const progress = +(payload.percent as number).toFixed(2);
setAppUpdateProgress(progress, payload.total);
break;
}

case 'update-not-available': {
const explicit = payload;
if (explicit) {
// the user has explicitly checked for an update via the Help menu;
// we should display some UI feedback if there are no updates available
setAppUpdateStatus(AppUpdaterStatus.UPDATE_UNAVAILABLE, undefined);
case 'update-in-progress': {
setAppUpdateStatus(AppUpdaterStatus.UPDATE_AVAILABLE, payload.version);
setAppUpdateShowing(true);
break;
}
break;
}

case 'update-downloaded':
setAppUpdateStatus(AppUpdaterStatus.UPDATE_SUCCEEDED, undefined);
setAppUpdateShowing(true);
break;
case 'update-not-available': {
const explicit = payload;
if (explicit) {
// the user has explicitly checked for an update via the Help menu;
// we should display some UI feedback if there are no updates available
setAppUpdateStatus(AppUpdaterStatus.UPDATE_UNAVAILABLE, undefined);
setAppUpdateShowing(true);
}
break;
}

case 'error':
setAppUpdateStatus(AppUpdaterStatus.UPDATE_FAILED, undefined);
setAppUpdateError(payload);
setAppUpdateShowing(true);
break;
case 'update-downloaded':
setAppUpdateStatus(AppUpdaterStatus.UPDATE_SUCCEEDED, undefined);
setAppUpdateShowing(true);
break;

default:
break;
case 'error':
setAppUpdateStatus(AppUpdaterStatus.UPDATE_FAILED, undefined);
setAppUpdateError(payload);
setAppUpdateShowing(true);
break;

case 'breaking-update-available':
if (breakingMetaData) {
setBreakingMetaData(breakingMetaData);
setAppUpdateStatus(AppUpdaterStatus.BREAKING_UPDATE_AVAILABLE, payload.version);
setAppUpdateShowing(true);
}
break;

default:
break;
}
}
});
);
}, []);

const title = useMemo(() => {
Expand Down Expand Up @@ -292,6 +318,19 @@ export const AppUpdater: React.FC<{}> = () => {
const subText =
status === AppUpdaterStatus.UPDATE_AVAILABLE ? `${formatMessage('Bot Framework Composer')} v${version}` : '';

if (status === AppUpdaterStatus.BREAKING_UPDATE_AVAILABLE && showing && breakingMetaData) {
const BreakingUpdateUx = breakingUpdatesMap[breakingMetaData.uxId];
// TODO: check if breaking update ux component is defined and handle undefined case
return (
<BreakingUpdateUx
explicitCheck={breakingMetaData.explicitCheck}
version={version}
onCancel={handleDismiss}
onContinue={handleContinueFromBreakingUx}
/>
);
}

return showing ? (
<Dialog
dialogContentProps={{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import React from 'react';
import { BreakingUpdateId } from '@botframework-composer/types';

import { BreakingUpdateProps } from './types';
import { Version1To2Content } from './version1To2';

/**
* A map of breaking update identifiers to the React components responsible
* for showing each breaking update's special UX before proceeding to the
* standard update flow.
*
* Ex. 'Version2.5.xTo3.x.x': DialogWithDisclaimerAndDocsAboutNewChanges
*/

export const breakingUpdatesMap: Record<BreakingUpdateId, React.FC<BreakingUpdateProps>> = {
'Version1.x.xTo2.x.x': Version1To2Content,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export type BreakingUpdateProps = {
explicitCheck: boolean;
/** Called when the user dismisses the breaking changes UX; stops the update flow completely. */
onCancel: () => void;
/** Called when the breaking changes UX is ready to continue into the normal update flow. */
onContinue: () => void;
version?: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

/** @jsx jsx */
import { jsx, css } from '@emotion/core';
import React, { useCallback, useState } from 'react';
import { DefaultButton, PrimaryButton, IButtonStyles } from 'office-ui-fabric-react/lib/Button';
import { Dialog, DialogType, IDialogContentStyles } from 'office-ui-fabric-react/lib/Dialog';
import { Link } from 'office-ui-fabric-react/lib/Link';
import { NeutralColors } from '@uifabric/fluent-theme';
import formatMessage from 'format-message';
import { useRecoilValue } from 'recoil';

import { dispatcherState, userSettingsState } from '../../../recoilModel';

import { BreakingUpdateProps } from './types';

const dismissButton: Partial<IButtonStyles> = {
root: {
marginRight: '6px;',
marginLeft: 'auto',
},
};

const dialogContent: Partial<IDialogContentStyles> = {
content: { color: NeutralColors.black },
};

const dialogContentWithoutHeader: Partial<IDialogContentStyles> = {
...dialogContent,
header: {
display: 'none',
},
inner: {
padding: '36px 24px 24px 24px',
},
};

const buttonRow = css`
display: flex;
flex-flow: row nowrap;
justify-items: flex-end;
`;

const gotItButton = css`
margin-left: auto;
`;

const updateCancelledCopy = css`
margin-top: 0;
margin-bottom: 27px;
`;

type ModalState = 'Default' | 'PressedNotNow';

export const Version1To2Content: React.FC<BreakingUpdateProps> = (props) => {
const { explicitCheck, onCancel, onContinue } = props;
const [currentState, setCurrentState] = useState<ModalState>('Default');
const userSettings = useRecoilValue(userSettingsState);
const { updateUserSettings } = useRecoilValue(dispatcherState);
const onNotNow = useCallback(() => {
if (userSettings.appUpdater.autoDownload) {
// disable auto update and notify the user
updateUserSettings({
appUpdater: {
autoDownload: false,
},
});
setCurrentState('PressedNotNow');
} else {
onCancel();
}
}, []);

return currentState === 'Default' ? (
<Dialog
dialogContentProps={{
styles: dialogContent,
title: formatMessage('Composer 2.0 is now available!'),
type: DialogType.largeHeader,
}}
hidden={false}
maxWidth={427}
minWidth={427}
modalProps={{
isBlocking: false,
}}
>
<p>
{formatMessage(
'Bot Framework Composer 2.0 provides more built-in capabilities so you can build complex bots quickly. Update to Composer 2.0 for advanced bot templates, prebuilt components, and a runtime that is fully extensible through packages.'
)}
</p>

<p>
{formatMessage.rich(
'Note: If your bot is using custom actions, they will not be supported in Composer 2.0. <a>Learn more about updating to Composer 2.0.</a>',
{
// TODO: needs real link
a: ({ children }) => (
<Link key="v2-breaking-changes-docs" href="https://aka.ms/bot-framework-composer-2.0">
Comment thread
srinaath marked this conversation as resolved.
{children}
</Link>
),
}
)}
</p>
<div css={buttonRow}>
{explicitCheck ? (
<DefaultButton styles={dismissButton} text={formatMessage('Cancel')} onClick={onCancel} />
) : (
<DefaultButton styles={dismissButton} text={formatMessage('Not now')} onClick={onNotNow} />
)}
<PrimaryButton text={formatMessage('Update and restart')} onClick={onContinue} />
</div>
</Dialog>
) : (
<Dialog
dialogContentProps={{
styles: dialogContentWithoutHeader,
title: undefined,
type: DialogType.normal,
}}
hidden={false}
maxWidth={427}
minWidth={427}
modalProps={{
isBlocking: false,
}}
>
<p css={updateCancelledCopy}>
{formatMessage.rich(
'Update cancelled. Auto-update has been turned off for this release. You can update at any time by selecting <b>Help > Check for updates.</b>',
{ b: ({ children }) => <b key="v2-breaking-changes-re-enable-auto-updates">{children}</b> }
)}
</p>
<div css={buttonRow}>
<PrimaryButton css={gotItButton} text={formatMessage('Got it!')} onClick={onCancel} />
</div>
</Dialog>
);
};
4 changes: 4 additions & 0 deletions Composer/packages/client/src/components/AppUpdater/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

export { AppUpdater } from './AppUpdater';
1 change: 1 addition & 0 deletions Composer/packages/client/src/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ export const SupportedFileTypes = [
export const USER_TOKEN_STORAGE_KEY = 'composer.userToken';

export enum AppUpdaterStatus {
BREAKING_UPDATE_AVAILABLE,
IDLE,
UPDATE_AVAILABLE,
UPDATE_UNAVAILABLE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const applicationDispatcher = () => {
const newAppUpdateState = {
...currentAppUpdate,
};
if (status === AppUpdaterStatus.UPDATE_AVAILABLE) {
if (status === AppUpdaterStatus.UPDATE_AVAILABLE || status === AppUpdaterStatus.BREAKING_UPDATE_AVAILABLE) {
newAppUpdateState.version = version;
}
if (status === AppUpdaterStatus.IDLE) {
Expand Down
Loading