Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
- Added sliding dots typing indicator in Fluent theme, in PR [#5447](https://github.com/microsoft/BotFramework-WebChat/pull/5447) and PR [#5448](https://github.com/microsoft/BotFramework-WebChat/pull/5448), by [@compulim](https://github.com/compulim)
- (Experimental) Add an ability to pass `completion` prop into Fluent send box and expose the component, in PR [#5466](https://github.com/microsoft/BotFramework-WebChat/pull/5466), by [@OEvgeny](https://github.com/OEvgeny)
- Added feedback form for like/dislike button when `feedbackActionsPlacement` is `"activity-actions"`, in PR [#5460](https://github.com/microsoft/BotFramework-WebChat/pull/5460), PR [#5469](https://github.com/microsoft/BotFramework-WebChat/pull/5469), and PR [5470](https://github.com/microsoft/BotFramework-WebChat/pull/5470) by [@lexi-taylor](https://github.com/lexi-taylor) and [@OEvgeny](https://github.com/OEvgeny)
- <kbd>ESCAPE</kbd> key should reset the feedback form, in PR [#5480](https://github.com/microsoft/BotFramework-WebChat/pull/5480), by [@compulim](https://github.com/compulim)
- <kbd>ESCAPE</kbd> key should reset the feedback form, in PR [#5480](https://github.com/microsoft/BotFramework-WebChat/pull/5480), by [@compulim](https://github.com/compulim), in PR [#5493](https://github.com/microsoft/BotFramework-WebChat/pull/5493) by [@lexi-taylor](https://github.com/lexi-taylor)
- Added multi-dimensional grouping, `styleOptions.groupActivitiesBy`, and `useGroupActivitiesByName` hook, in PR [#5471](https://github.com/microsoft/BotFramework-WebChat/pull/5471), by [@compulim](https://github.com/compulim)
- Existing behavior will be kept and activities will be grouped by `sender` followed by `status`
- `useGroupActivitiesByName` is favored over the existing `useGroupActivities` hook for performance reason
Expand Down
6 changes: 3 additions & 3 deletions __tests__/html2/feedbackForm/feedback.form.activity.html
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@
document.querySelectorAll(`[data-testid="${testIds.feedbackButton}"]`)[0]
);

return await host.snapshot('local');
// THEN: Should match snapshot.
await host.snapshot('local');

// WHEN: Click on dislike button to re-open feedback form
await host.sendTab(1);
await host.sendKeys('SPACE');
await host.sendKeys('RIGHT', 'SPACE');

await pageConditions.became(
'feedback form is open',
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.
102 changes: 102 additions & 0 deletions __tests__/html2/feedbackForm/feedback.form.emptyFeedback.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<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>
</head>

<body>
<main id="webchat"></main>
<script type="module">
run(async function () {
const {
WebChat: { renderWebChat, testIds }
} = window; // Imports in UMD fashion.

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

renderWebChat(
{
directLine,
store,
styleOptions: { feedbackActionsPlacement: 'activity-actions' }
},
document.getElementById('webchat')
);

await pageConditions.uiConnected();
pageElements.byTestId(testIds.sendBoxTextBox).focus();

// GIVEN: An activity with feedback form.
await directLine.emulateIncomingActivity({
type: 'message',
id: 'a-00000',
timestamp: 0,
text: 'This is a test message to show feedback buttons',
from: {
role: 'bot'
},
locale: 'en-US',
entities: [],
channelData: {
feedbackLoop: {
type: 'default',
disclaimer: 'This is a test disclaimer message'
}
}
});

await pageConditions.numActivitiesShown(1);

// WHEN: Focus on the like button.
await host.sendShiftTab(3);
await host.sendKeys('ENTER', 'SPACE');

// THEN: The feedback form should be expanded.
await pageConditions.became(
'feedback form is open',
() => document.activeElement === pageElements.byTestId(testIds.feedbackSendBox),
1000
);

// WHEN: An empty feedback is being submitted.
const { activity } = await directLine.actPostActivity(async () => {
await host.sendTab(1);
await host.sendKeys('ENTER');
});

// THEN: Should post a "message/submitAction".
expect(activity).toEqual(
expect.objectContaining({
type: 'invoke',
name: 'message/submitAction',
value: {
actionName: 'feedback',
actionValue: {
reaction: 'like',
feedback: {
feedbackText: ''
}
}
}
})
);

// THEN: Feedback form should be collapsed.
await expect(pageElements.byTestId(testIds.feedbackSendBox)).toBeFalsy();

// THEN: All feedback buttons should be grayed out.
await expect(
Array.from(pageElements.allByTestId(testIds.feedbackButton)).every(
buttonElement => buttonElement.getAttribute('aria-disabled') === 'true'
)
).toBe(true);

// THEN: Should match snapshot.
await host.snapshot('local');
});
</script>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type WebChatActivity } from 'botframework-webchat-core';
import { hasDisclaimer } from './hasFeedbackLoop';

/**
* @deprecated
* @deprecated This helper function should only use for patching the service. After patching, should use `getDisclaimerFromReviewAction` instead.
*/
export default function getDisclaimer(activity: WebChatActivity): string | undefined {
return hasDisclaimer(activity) ? activity.channelData.feedbackLoop.disclaimer : undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const feedbackLoopSchema = union([
type FeedbackActivity = WebChatActivity & InferOutput<typeof feedbackLoopSchema>;

/**
* @deprecated
* @deprecated This helper function should only use for patching the service. After patching, should use `getDisclaimerFormReviewAction` instead.
*/
export function hasDisclaimer(
activity: WebChatActivity
Expand All @@ -35,7 +35,7 @@ export function hasDisclaimer(
}

/**
* @deprecated
* @deprecated This helper function should only use for patching the service. After patching, should use `isActionRequireReview` instead.
*/
export default function hasFeedbackLoop(activity: WebChatActivity): activity is FeedbackActivity {
return safeParse(feedbackLoopSchema, activity).success;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { hooks } from 'botframework-webchat-api';
import { reactNode, validateProps } from 'botframework-webchat-react-valibot';
import {
getOrgSchemaMessage,
parseAction,
type OrgSchemaAction,
type WebChatActivity
} from 'botframework-webchat-core';
import { reactNode, validateProps } from 'botframework-webchat-react-valibot';
import random from 'math-random';
import React, { memo, useCallback, useMemo, useRef, useState, type Dispatch, type SetStateAction } from 'react';
import { wrapWith } from 'react-wrap-with';
Expand All @@ -19,6 +19,7 @@ import getDisclaimerFromFeedbackLoop from '../private/getDisclaimerFromFeedbackL
import hasFeedbackLoop from '../private/hasFeedbackLoop';
import ActivityFeedbackContext, { type ActivityFeedbackContextType } from './private/ActivityFeedbackContext';
import { ActivityFeedbackFocusPropagationScope, usePropagateActivityFeedbackFocus } from './private/FocusPropagation';
import isActionRequireReview from '../private/isActionRequireReview';

const { usePonyfill, usePostActivity } = hooks;

Expand Down Expand Up @@ -220,15 +221,15 @@ function ActivityFeedbackComposer(props: ActivityFeedbackComposerProps) {
const isLegacyAction = action['@type'] === 'VoteAction';

// TODO: We should update this to use W3C Hydra.1
if (typeof feedbackText !== 'undefined') {
if (isActionRequireReview(action)) {
postActivity({
name: 'message/submitAction',
replyToId: activityRef.current.id,
type: 'invoke',
value: {
actionName: 'feedback',
actionValue: {
feedback: { feedbackText },
feedback: { feedbackText: feedbackText || '' },
reaction: action['@type'] === 'LikeAction' ? 'like' : 'dislike'
}
}
Expand Down
Loading