Skip to content

Commit 05eb3a0

Browse files
committed
some test updates
1 parent 0c16cbe commit 05eb3a0

10 files changed

Lines changed: 85 additions & 74 deletions

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
await host.snapshot('local');
6767

6868
// Dismiss like button
69-
await host.sendShiftTab(1);
69+
await host.sendShiftTab(2);
7070
await host.sendKeys('ENTER');
7171

7272
await host.snapshot('local');
@@ -102,6 +102,9 @@
102102
);
103103

104104
await host.sendKeys('Test feedback');
105+
106+
await host.snapshot('local');
107+
105108
const { activity } = await directLine.actPostActivity(async () => {
106109
await host.sendTab(1);
107110
await host.sendKeys('ENTER');
@@ -116,7 +119,7 @@
116119
actionValue: {
117120
reaction: 'dislike',
118121
feedback: {
119-
feedbackText: expect.any('Test feedback')
122+
feedbackText: 'Test feedback'
120123
}
121124
}
122125
}
-48 Bytes
Loading
13.7 KB
Loading
13.4 KB
Loading
22 KB
Loading
13.4 KB
Loading

packages/component/src/Activity/ActivityFeedback.tsx

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import { hooks } from 'botframework-webchat-api';
22
import { getOrgSchemaMessage, OrgSchemaAction, parseAction, WebChatActivity } from 'botframework-webchat-core';
33
import classNames from 'classnames';
4-
import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
4+
import React, { memo, useCallback, useMemo, useState } from 'react';
55
import { defaultFeedbackEntities } from './private/DefaultFeedbackEntities';
66
import { hasFeedbackLoop, getDisclaimer } from './private/feedbackActivity.util';
77

88
import Feedback from './private/Feedback';
99
import dereferenceBlankNodes from '../Utils/JSONLinkedData/dereferenceBlankNodes';
1010
import FeedbackForm from './private/FeedbackForm';
1111
import { useStyleToEmotionObject } from '../hooks/internal/styleToEmotionObject';
12-
import { useRefFrom } from 'use-ref-from';
1312

14-
const { useStyleOptions, usePostActivity, usePonyfill } = hooks;
13+
const { useStyleOptions } = hooks;
1514

1615
type ActivityFeedbackProps = Readonly<{
1716
activity: WebChatActivity;
@@ -43,15 +42,9 @@ const useGetMessageThing = (activity: WebChatActivity) =>
4342
return { isFeedbackLoopSupported: false, messageThing, graph };
4443
}, [activity]);
4544

46-
const DEBOUNCE_TIMEOUT = 500;
47-
4845
function ActivityFeedback({ activity }: ActivityFeedbackProps) {
49-
const [{ clearTimeout, setTimeout }] = usePonyfill();
50-
const postActivity = usePostActivity();
51-
5246
const [{ feedbackActionsPlacement }] = useStyleOptions();
5347
const rootClassName = useStyleToEmotionObject()(ROOT_STYLE) + '';
54-
const postActivityRef = useRefFrom(postActivity);
5548

5649
const [selectedAction, setSelectedAction] = useState<OrgSchemaAction | undefined>();
5750

@@ -78,28 +71,12 @@ function ActivityFeedback({ activity }: ActivityFeedbackProps) {
7871
return Object.freeze(new Set([] as OrgSchemaAction[]));
7972
}, [graph, messageThing?.potentialAction]);
8073

81-
const handleFeedbackActionClick = useCallback((action?: OrgSchemaAction) => {
82-
setSelectedAction(action);
83-
}, []);
84-
85-
useEffect(() => {
86-
if (!selectedAction) {
87-
return;
88-
}
89-
90-
const timeout = setTimeout(
91-
() =>
92-
// TODO: We should update this to use W3C Hydra.1
93-
postActivityRef.current({
94-
entities: [selectedAction],
95-
name: 'webchat:activity-status/feedback',
96-
type: 'event'
97-
} as any),
98-
DEBOUNCE_TIMEOUT
99-
);
100-
101-
return () => clearTimeout(timeout);
102-
}, [clearTimeout, postActivityRef, selectedAction, setTimeout]);
74+
const handleFeedbackActionClick = useCallback(
75+
(action?: OrgSchemaAction) => {
76+
setSelectedAction(action === selectedAction ? undefined : action);
77+
},
78+
[selectedAction]
79+
);
10380

10481
const FeedbackComponent = useMemo(
10582
() => (
@@ -108,10 +85,12 @@ function ActivityFeedback({ activity }: ActivityFeedbackProps) {
10885
className={classNames({
10986
'webchat__thumb-button--large': feedbackActionsPlacement === 'activity-actions'
11087
})}
88+
isFeedbackFormSupported={isFeedbackLoopSupported}
11189
onHandleFeedbackActionClick={handleFeedbackActionClick}
90+
selectedAction={selectedAction}
11291
/>
11392
),
114-
[feedbackActions, feedbackActionsPlacement, handleFeedbackActionClick]
93+
[feedbackActions, feedbackActionsPlacement, handleFeedbackActionClick, isFeedbackLoopSupported, selectedAction]
11594
);
11695

11796
const FeedbackFormComponent = useMemo(

packages/component/src/Activity/private/Feedback.tsx

Lines changed: 64 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,82 @@
11
import { hooks } from 'botframework-webchat-api';
22
import { type OrgSchemaAction } from 'botframework-webchat-core';
3-
import React, { Fragment, memo, useMemo, type PropsWithChildren } from 'react';
3+
import React, { Fragment, memo, useEffect, useMemo, type PropsWithChildren } from 'react';
4+
import { useRefFrom } from 'use-ref-from';
45

56
import FeedbackVoteButton from './VoteButton';
67

7-
const { useLocalizer } = hooks;
8+
const { usePonyfill, usePostActivity, useLocalizer } = hooks;
89

910
type Props = Readonly<
1011
PropsWithChildren<{
1112
actions: ReadonlySet<OrgSchemaAction>;
1213
className?: string | undefined;
14+
isFeedbackFormSupported?: boolean;
1315
onHandleFeedbackActionClick?: (action: OrgSchemaAction) => void;
1416
selectedAction?: OrgSchemaAction | undefined;
1517
}>
1618
>;
1719

18-
const Feedback = memo(({ actions, className, onHandleFeedbackActionClick, selectedAction }: Props) => {
19-
const localize = useLocalizer();
20-
21-
const actionProps = useMemo(
22-
() =>
23-
[...actions].some(action => action.actionStatus === 'CompletedActionStatus')
24-
? {
25-
disabled: true,
26-
title: localize('VOTE_COMPLETE_ALT')
27-
}
28-
: undefined,
29-
[actions, localize]
30-
);
31-
32-
return (
33-
<Fragment>
34-
{[...actions].map((action, index) => (
35-
<FeedbackVoteButton
36-
action={action}
37-
className={className}
38-
key={action['@id'] || index}
39-
onClick={onHandleFeedbackActionClick}
40-
pressed={
41-
selectedAction === action ||
42-
action.actionStatus === 'CompletedActionStatus' ||
43-
action.actionStatus === 'ActiveActionStatus'
44-
}
45-
{...actionProps}
46-
/>
47-
))}
48-
</Fragment>
49-
);
50-
});
20+
const DEBOUNCE_TIMEOUT = 500;
21+
22+
const Feedback = memo(
23+
({ actions, className, isFeedbackFormSupported, onHandleFeedbackActionClick, selectedAction }: Props) => {
24+
const [{ clearTimeout, setTimeout }] = usePonyfill();
25+
const postActivity = usePostActivity();
26+
const localize = useLocalizer();
27+
28+
const postActivityRef = useRefFrom(postActivity);
29+
30+
useEffect(() => {
31+
if (!selectedAction || isFeedbackFormSupported) {
32+
return;
33+
}
34+
35+
const timeout = setTimeout(
36+
() =>
37+
// TODO: We should update this to use W3C Hydra.1
38+
postActivityRef.current({
39+
entities: [selectedAction],
40+
name: 'webchat:activity-status/feedback',
41+
type: 'event'
42+
} as any),
43+
DEBOUNCE_TIMEOUT
44+
);
45+
46+
return () => clearTimeout(timeout);
47+
}, [clearTimeout, isFeedbackFormSupported, postActivityRef, selectedAction, setTimeout]);
48+
49+
const actionProps = useMemo(
50+
() =>
51+
[...actions].some(action => action.actionStatus === 'CompletedActionStatus')
52+
? {
53+
disabled: true,
54+
title: localize('VOTE_COMPLETE_ALT')
55+
}
56+
: undefined,
57+
[actions, localize]
58+
);
59+
60+
return (
61+
<Fragment>
62+
{[...actions].map((action, index) => (
63+
<FeedbackVoteButton
64+
action={action}
65+
className={className}
66+
key={action['@id'] || index}
67+
onClick={onHandleFeedbackActionClick}
68+
pressed={
69+
selectedAction === action ||
70+
action.actionStatus === 'CompletedActionStatus' ||
71+
action.actionStatus === 'ActiveActionStatus'
72+
}
73+
{...actionProps}
74+
/>
75+
))}
76+
</Fragment>
77+
);
78+
}
79+
);
5180

5281
Feedback.displayName = 'ActivityStatusFeedback';
5382

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { type WebChatActivity } from 'botframework-webchat-core';
2-
import { object, safeParse, string } from 'valibot';
2+
import { literal, object, safeParse, string } from 'valibot';
33

44
const activityWithFeedbackLoopSchema = object({
55
channelData: object({
66
feedbackLoop: object({
7-
type: string(),
7+
type: literal('default'),
88
disclaimer: string()
99
})
1010
})
@@ -15,7 +15,7 @@ type FeedbackActivity = WebChatActivity & {
1515
};
1616

1717
export const hasFeedbackLoop = (activity: WebChatActivity): activity is FeedbackActivity =>
18-
safeParse(activityWithFeedbackLoopSchema, activity.channelData).success;
18+
safeParse(activityWithFeedbackLoopSchema, activity).success;
1919

2020
export const getDisclaimer = (activity: WebChatActivity): string | undefined =>
2121
hasFeedbackLoop(activity) ? activity.channelData.feedbackLoop.disclaimer : undefined;

packages/component/src/Styles/StyleSet/FeedbackTextArea.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default function createFeedbackTextAreaStyle() {
2121
'&::after': {
2222
borderBottomLeftRadius: '4px',
2323
borderBottomRightRadius: '4px',
24-
borderBottom: `3px solid ${CSSTokens.FeedbackFormNeutralLight}`,
24+
borderBottom: `3px solid ${CSSTokens.FeedbackFormPrimary}`,
2525
bottom: '-1px',
2626
clipPath: 'inset(calc(100% - 3px) 50% 0 50%)',
2727
content: '""',
@@ -32,7 +32,7 @@ export default function createFeedbackTextAreaStyle() {
3232
transition: 'clip-path 0 cubic-bezier(1, 0, 1, 1)'
3333
},
3434
'&:focus-within': {
35-
border: `1px solid ${CSSTokens.FeedbackFormPrimary}`
35+
border: `1px solid ${CSSTokens.FeedbackFormNeutralLight}`
3636
},
3737
'&:focus-within::after': {
3838
clipPath: 'inset(calc(100% - 3px) 0 0 0)',

0 commit comments

Comments
 (0)