Skip to content

Commit 5981589

Browse files
lexi-taylorOEvgenycompulim
authored
Allow feedback form to be submitted without feedback text (#5493)
* allow feedback form to be submitted without text * Update packages/component/src/ActivityFeedback/providers/ActivityFeedbackComposer.tsx Co-authored-by: Eugene <EOlonov@gmail.com> * update changelog * Fix test * Use isActionRequireReview * Add tests * Comments * Removed tests * Update snapshots * Remove new line * Add deprecation notes --------- Co-authored-by: Eugene <EOlonov@gmail.com> Co-authored-by: William Wong <compulim@users.noreply.github.com>
1 parent d66bb72 commit 5981589

9 files changed

Lines changed: 113 additions & 10 deletions

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/
8888
- 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)
8989
- (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)
9090
- 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)
91-
- <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)
91+
- <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)
9292
- 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)
9393
- Existing behavior will be kept and activities will be grouped by `sender` followed by `status`
9494
- `useGroupActivitiesByName` is favored over the existing `useGroupActivities` hook for performance reason

__tests__/html2/feedbackForm/feedback.form.activity.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@
9090
document.querySelectorAll(`[data-testid="${testIds.feedbackButton}"]`)[0]
9191
);
9292

93-
return await host.snapshot('local');
93+
// THEN: Should match snapshot.
94+
await host.snapshot('local');
9495

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

9999
await pageConditions.became(
100100
'feedback form is open',
-1 Bytes
Loading
-1 Bytes
Loading
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!doctype html>
2+
<html lang="en-US">
3+
<head>
4+
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
5+
<script crossorigin="anonymous" src="/test-harness.js"></script>
6+
<script crossorigin="anonymous" src="/test-page-object.js"></script>
7+
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
8+
</head>
9+
10+
<body>
11+
<main id="webchat"></main>
12+
<script type="module">
13+
run(async function () {
14+
const {
15+
WebChat: { renderWebChat, testIds }
16+
} = window; // Imports in UMD fashion.
17+
18+
const { directLine, store } = testHelpers.createDirectLineEmulator();
19+
20+
renderWebChat(
21+
{
22+
directLine,
23+
store,
24+
styleOptions: { feedbackActionsPlacement: 'activity-actions' }
25+
},
26+
document.getElementById('webchat')
27+
);
28+
29+
await pageConditions.uiConnected();
30+
pageElements.byTestId(testIds.sendBoxTextBox).focus();
31+
32+
// GIVEN: An activity with feedback form.
33+
await directLine.emulateIncomingActivity({
34+
type: 'message',
35+
id: 'a-00000',
36+
timestamp: 0,
37+
text: 'This is a test message to show feedback buttons',
38+
from: {
39+
role: 'bot'
40+
},
41+
locale: 'en-US',
42+
entities: [],
43+
channelData: {
44+
feedbackLoop: {
45+
type: 'default',
46+
disclaimer: 'This is a test disclaimer message'
47+
}
48+
}
49+
});
50+
51+
await pageConditions.numActivitiesShown(1);
52+
53+
// WHEN: Focus on the like button.
54+
await host.sendShiftTab(3);
55+
await host.sendKeys('ENTER', 'SPACE');
56+
57+
// THEN: The feedback form should be expanded.
58+
await pageConditions.became(
59+
'feedback form is open',
60+
() => document.activeElement === pageElements.byTestId(testIds.feedbackSendBox),
61+
1000
62+
);
63+
64+
// WHEN: An empty feedback is being submitted.
65+
const { activity } = await directLine.actPostActivity(async () => {
66+
await host.sendTab(1);
67+
await host.sendKeys('ENTER');
68+
});
69+
70+
// THEN: Should post a "message/submitAction".
71+
expect(activity).toEqual(
72+
expect.objectContaining({
73+
type: 'invoke',
74+
name: 'message/submitAction',
75+
value: {
76+
actionName: 'feedback',
77+
actionValue: {
78+
reaction: 'like',
79+
feedback: {
80+
feedbackText: ''
81+
}
82+
}
83+
}
84+
})
85+
);
86+
87+
// THEN: Feedback form should be collapsed.
88+
await expect(pageElements.byTestId(testIds.feedbackSendBox)).toBeFalsy();
89+
90+
// THEN: All feedback buttons should be grayed out.
91+
await expect(
92+
Array.from(pageElements.allByTestId(testIds.feedbackButton)).every(
93+
buttonElement => buttonElement.getAttribute('aria-disabled') === 'true'
94+
)
95+
).toBe(true);
96+
97+
// THEN: Should match snapshot.
98+
await host.snapshot('local');
99+
});
100+
</script>
101+
</body>
102+
</html>
13.2 KB
Loading

packages/component/src/ActivityFeedback/private/getDisclaimerFromFeedbackLoop.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { type WebChatActivity } from 'botframework-webchat-core';
33
import { hasDisclaimer } from './hasFeedbackLoop';
44

55
/**
6-
* @deprecated
6+
* @deprecated This helper function should only use for patching the service. After patching, should use `getDisclaimerFromReviewAction` instead.
77
*/
88
export default function getDisclaimer(activity: WebChatActivity): string | undefined {
99
return hasDisclaimer(activity) ? activity.channelData.feedbackLoop.disclaimer : undefined;

packages/component/src/ActivityFeedback/private/hasFeedbackLoop.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const feedbackLoopSchema = union([
2626
type FeedbackActivity = WebChatActivity & InferOutput<typeof feedbackLoopSchema>;
2727

2828
/**
29-
* @deprecated
29+
* @deprecated This helper function should only use for patching the service. After patching, should use `getDisclaimerFormReviewAction` instead.
3030
*/
3131
export function hasDisclaimer(
3232
activity: WebChatActivity
@@ -35,7 +35,7 @@ export function hasDisclaimer(
3535
}
3636

3737
/**
38-
* @deprecated
38+
* @deprecated This helper function should only use for patching the service. After patching, should use `isActionRequireReview` instead.
3939
*/
4040
export default function hasFeedbackLoop(activity: WebChatActivity): activity is FeedbackActivity {
4141
return safeParse(feedbackLoopSchema, activity).success;

packages/component/src/ActivityFeedback/providers/ActivityFeedbackComposer.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { hooks } from 'botframework-webchat-api';
2-
import { reactNode, validateProps } from 'botframework-webchat-react-valibot';
32
import {
43
getOrgSchemaMessage,
54
parseAction,
65
type OrgSchemaAction,
76
type WebChatActivity
87
} from 'botframework-webchat-core';
8+
import { reactNode, validateProps } from 'botframework-webchat-react-valibot';
99
import random from 'math-random';
1010
import React, { memo, useCallback, useMemo, useRef, useState, type Dispatch, type SetStateAction } from 'react';
1111
import { wrapWith } from 'react-wrap-with';
@@ -19,6 +19,7 @@ import getDisclaimerFromFeedbackLoop from '../private/getDisclaimerFromFeedbackL
1919
import hasFeedbackLoop from '../private/hasFeedbackLoop';
2020
import ActivityFeedbackContext, { type ActivityFeedbackContextType } from './private/ActivityFeedbackContext';
2121
import { ActivityFeedbackFocusPropagationScope, usePropagateActivityFeedbackFocus } from './private/FocusPropagation';
22+
import isActionRequireReview from '../private/isActionRequireReview';
2223

2324
const { usePonyfill, usePostActivity } = hooks;
2425

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

222223
// TODO: We should update this to use W3C Hydra.1
223-
if (typeof feedbackText !== 'undefined') {
224+
if (isActionRequireReview(action)) {
224225
postActivity({
225226
name: 'message/submitAction',
226227
replyToId: activityRef.current.id,
227228
type: 'invoke',
228229
value: {
229230
actionName: 'feedback',
230231
actionValue: {
231-
feedback: { feedbackText },
232+
feedback: { feedbackText: feedbackText || '' },
232233
reaction: action['@type'] === 'LikeAction' ? 'like' : 'dislike'
233234
}
234235
}

0 commit comments

Comments
 (0)