Skip to content

Commit

Permalink
feat: Add decorators (#5205)
Browse files Browse the repository at this point in the history
* Add decorators

* Fix lint

* Rework into a single ActivityBorder middleware stack

* Add test

* Add William's suggestions

Co-authored-by: William Wong <[email protected]>

* Polish

* Remove Fluent Decorator and update test

* Roll own Proxy implementation to bypass missing context

* Update test

* Rework according to RCoR changes

* Changelog

* Tweak changelog

* Update RCoR

* Sort

* Typo and sort

* Better type checking

* Sort

* Sort

* Sort

* Newline

* Newline

* Code styling

* Props optional/undefined

* Code styling

* Clean up

* Use EmptyObject for props instead of {} any

* Sort and typo

* Converge templateMiddleware and build user story

* Fix no middleware and stabilize middleware prop

* Refactor init

* Fix type

---------

Co-authored-by: William Wong <[email protected]>
  • Loading branch information
OEvgeny and compulim authored Jun 18, 2024
1 parent 745a603 commit 6c3063d
Show file tree
Hide file tree
Showing 39 changed files with 1,103 additions and 145 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/

## [Unreleased]

### Added

- (Experimental) Added initial decorators support, in PR [#5205](https://github.com/microsoft/BotFramework-WebChat/pull/5205), by [@OEvgeny](https://github.com/OEvgeny)
- Introduced internal `botframework-webchat-api/decorator` import, in PR [#5205](https://github.com/microsoft/BotFramework-WebChat/pull/5205), by [@OEvgeny](https://github.com/OEvgeny)
- Added `DecoratorComposer` and `ActivityDecorator` to be used for decorating activity border, in PR [#5205](https://github.com/microsoft/BotFramework-WebChat/pull/5205), by [@OEvgeny](https://github.com/OEvgeny)

### Fixed

- Improved performance for `useActivityWithRenderer`, in PR [#5172](https://github.com/microsoft/BotFramework-WebChat/pull/5172), by [@OEvgeny](https://github.com/OEvgeny)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
149 changes: 149 additions & 0 deletions __tests__/html/fluentTheme/withDecorator.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
<style>
.flair {
border-radius: inherit;
border: solid 2px red;
}

.loader {
border-bottom: solid 4px blue;
}
</style>
</head>
<body>
<main id="webchat"></main>
<script type="text/babel">
run(async function () {
const {
React,
ReactDOM: { render },
WebChat: {
decorator: { DecoratorComposer },
FluentThemeProvider,
ReactWebChat
}
} = window; // Imports in UMD fashion.

function Flair({ children }) {
return <div className="flair">{children}</div>;
}

function Loader({ children }) {
return <div className="loader">{children}</div>;
}

const decoratorMiddleware = [
init => init === 'activity border' && (next => request => (request.state === 'completion' ? Flair : next(request))),
init => init === 'activity border' && (next => request => (request.state === 'informative' ? Loader : next(request)))
];

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => <ReactWebChat
directLine={directLine}
store={store}
styleOptions={{
bubbleBorderRadius: 10,
typingAnimationBackgroundImage: `url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAUACgDASIAAhEBAxEB/8QAGgABAQACAwAAAAAAAAAAAAAAAAYCBwMFCP/EACsQAAECBQIEBQUAAAAAAAAAAAECAwAEBQYRBxITIjFBMlFhccFScoGh8f/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwD0lctx023JVD9UeKOIcNoSNylkdcCMbauSmXHLOPUx8r4ZAcQtO1SM9Mj5iO1gtWo1syc7S2zMKYSptbIPNgnII8/5HBpRZ9RpaKjNVVCpUzLPAQ1nmA7qPl6fmAondRrcaqhkVTiiQrYXgglsH7vnpHc3DcNNoEimaqT4Q2s4bCRuUs+gEaLd05uNFVMmiS3o3YEwFDhlP1Z7e3WLzUuzahUKHRk0zM07TmeApvOFLGEjcM9+Xp6wFnbN0Uu5GnF0x4qW1je2tO1Sc9Djy9oRD6QWlU6PPzVSqjRlgtksttKPMcqBKiO3h/cIDacIQgEIQgEIQgP/2Q==')`
}}
/>;

render(
<FluentThemeProvider>
<DecoratorComposer middleware={decoratorMiddleware}>
<App />
</DecoratorComposer>
</FluentThemeProvider>,
document.getElementById('webchat')
);

await pageConditions.uiConnected();

await directLine.emulateIncomingActivity({
channelData: {
streamType: 'informative'
},
from: {
id: 'u-00001',
name: 'Bot',
role: 'bot'
},
id: 'm-00001',
text: 'Working on it...',
type: 'message'
});

await directLine.emulateIncomingActivity({
channelData: {
streamType: 'informative'
},
from: {
id: 'u-00001',
name: 'Bot',
role: 'bot'
},
id: 't-00001',
text: 'Working on it...',
type: 'typing'
});

await pageConditions.typingIndicatorShown();
await pageConditions.numActivitiesShown(1);
await host.snapshot();

const attachments = [
{
content: {
type: 'AdaptiveCard',
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
version: '1.5',
actions: [
{ type: 'Action.Submit', title: 'Button 1' },
{
type: 'Action.ShowCard',
title: 'Show card',
card: {
type: 'AdaptiveCard',
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
version: '1.5',
actions: [
{ type: 'Action.Submit', title: 'Button 2' },
{ type: 'Action.Submit', title: 'Button 3' }
]
}
}
]
},
contentType: 'application/vnd.microsoft.card.adaptive'
}
];
await directLine.emulateIncomingActivity({
id: 'm-00001',
from: {
id: 'u-00001',
name: 'Bot',
role: 'bot'
},
text: 'Work completed!',
channelData: { streamType: 'completion' },
attachments
});

await pageConditions.numActivitiesShown(1);

// THEN: Should render the activity.
await host.snapshot();
});
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions __tests__/html/fluentTheme/withDecorator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('Fluent theme applied', () => {
test('with decorators', () => runHTML('fluentTheme/withDecorator'));
});
Loading

0 comments on commit 6c3063d

Please sign in to comment.