fix: PostbackInput

This commit is contained in:
yassinedorbozgithub 2024-11-27 17:56:32 +01:00
parent eb7d6ebe3c
commit 3be6006380

View File

@ -9,6 +9,7 @@
import { import {
Autocomplete, Autocomplete,
Box, Box,
Chip,
CircularProgress, CircularProgress,
InputAdornment, InputAdornment,
Skeleton, Skeleton,
@ -26,6 +27,7 @@ import {
ButtonType, ButtonType,
PayloadType, PayloadType,
PostBackButton, PostBackButton,
QuickReplyType,
StdOutgoingButtonsMessage, StdOutgoingButtonsMessage,
StdOutgoingQuickRepliesMessage, StdOutgoingQuickRepliesMessage,
StdQuickReply, StdQuickReply,
@ -37,9 +39,8 @@ type PayloadOption = PayloadPattern & {
group: string; group: string;
}; };
const isSamePostback = <T extends PayloadPattern>(a: T, b: T) => { const isSamePostback = <T extends PayloadPattern>(a: T, b: T) =>
return a.label === b.label && a.value === b.value; a.label === b.label && a.value === b.value;
};
type PostbackInputProps = { type PostbackInputProps = {
defaultValue?: PayloadPattern; defaultValue?: PayloadPattern;
@ -89,28 +90,24 @@ export const PostbackInput = ({
() => () =>
(block?.previousBlocks || []) (block?.previousBlocks || [])
.map((b) => getBlockFromCache(b)) .map((b) => getBlockFromCache(b))
.filter((b) => { .filter(
return b && typeof b.message === "object" && "buttons" in b.message; (b) => b && typeof b.message === "object" && "buttons" in b.message,
}) )
.map((b) => b as IBlock) .map((b) => b as IBlock)
.reduce((acc, b) => { .reduce((acc, b) => {
const postbackButtons = ( const postbackButtons = (
(b.message as StdOutgoingButtonsMessage)?.buttons || [] (b.message as StdOutgoingButtonsMessage)?.buttons || []
) )
.filter((btn) => btn.type === ButtonType.postback) .filter((btn) => btn.type === ButtonType.postback)
.map((btn) => { .map((btn) => ({ ...btn, group: b.name }));
return { ...btn, group: b.name };
});
return acc.concat(postbackButtons); return acc.concat(postbackButtons);
}, [] as (PostBackButton & { group: string })[]) }, [] as (PostBackButton & { group: string })[])
.map((btn) => { .map((btn) => ({
return {
label: btn.title, label: btn.title,
value: btn.payload, value: btn.payload,
group: btn.group, group: "buttons",
}; })),
}),
[block?.previousBlocks, getBlockFromCache], [block?.previousBlocks, getBlockFromCache],
); );
// Gather previous blocks quick replies // Gather previous blocks quick replies
@ -118,32 +115,27 @@ export const PostbackInput = ({
() => () =>
(block?.previousBlocks || []) (block?.previousBlocks || [])
.map((b) => getBlockFromCache(b)) .map((b) => getBlockFromCache(b))
.filter((b) => { .filter(
return ( (b) =>
b && typeof b.message === "object" && "quickReplies" in b.message b && typeof b.message === "object" && "quickReplies" in b.message,
); )
})
.map((b) => b as IBlock) .map((b) => b as IBlock)
.reduce((acc, b) => { .reduce((acc, b) => {
const postbackQuickReplies = ( const postbackQuickReplies = (
(b.message as StdOutgoingQuickRepliesMessage)?.quickReplies || [] (b.message as StdOutgoingQuickRepliesMessage)?.quickReplies || []
) )
.filter((btn) => btn.content_type === "text") .filter(({ content_type }) => content_type === QuickReplyType.text)
.map((btn) => { .map((btn) => ({ ...btn, group: b.name }));
return { ...btn, group: b.name };
});
return acc.concat(postbackQuickReplies); return acc.concat(postbackQuickReplies);
}, [] as (StdQuickReply & { group: string })[]) }, [] as (StdQuickReply & { group: string })[])
.map((btn) => { .map((btn) => ({
return {
id: btn.payload as string, id: btn.payload as string,
label: btn.title as string, label: btn.title as string,
value: btn.payload as string, value: btn.payload as string,
type: PayloadType.menu, type: PayloadType.menu,
group: btn.group, group: "quick_replies",
}; })),
}),
[block?.previousBlocks], [block?.previousBlocks],
); );
const menuOptions = menu const menuOptions = menu
@ -158,15 +150,13 @@ export const PostbackInput = ({
const contentOptions = useMemo( const contentOptions = useMemo(
() => () =>
(block?.previousBlocks || []) (block?.previousBlocks || [])
.map((bId) => getBlockFromCache(bId)) .map((bId) => getBlockFromCache(bId) as IBlock)
.filter((b) => { .filter(
return ( (b) =>
b && b &&
b.options?.content?.entity && b.options?.content?.entity &&
b.options.content.buttons.length > 0 b.options.content.buttons.length > 0,
); )
})
.map((b) => b as IBlock)
.map((b) => { .map((b) => {
const availableContents = (contents || []).filter( const availableContents = (contents || []).filter(
({ entity, status }) => ({ entity, status }) =>
@ -214,17 +204,14 @@ export const PostbackInput = ({
); );
} }
const selected = defaultValue const selected = defaultValue
? options.find((o) => { ? options.find((o) => isSamePostback(o, defaultValue))
return isSamePostback(o, defaultValue);
})
: undefined; : undefined;
return ( return (
<Autocomplete<PayloadOption> <Autocomplete
size="small" size="small"
defaultValue={selected} defaultValue={selected}
options={options} options={options}
// label={t("label.postback")}
multiple={false} multiple={false}
onChange={(_e, value) => { onChange={(_e, value) => {
setSelectedValue(value); setSelectedValue(value);
@ -236,20 +223,17 @@ export const PostbackInput = ({
onChange(null); onChange(null);
} }
}} }}
groupBy={(option) => { groupBy={({ group }) => group ?? t("label.other")}
return option.group ?? t("label.other");
}}
getOptionLabel={({ label }) => label} getOptionLabel={({ label }) => label}
renderGroup={(params) => ( renderGroup={({ key, group, children }) => (
<li key={params.key}> <li key={key}>
<Typography component="h4" p={2} fontWeight={700} color="primary"> <Typography component="h4" p={2} fontWeight={700} color="primary">
{t(`label.${params.group}`)} {t(`label.${group}`)}
</Typography> </Typography>
<Box>{params.children}</Box> <Box>{children}</Box>
</li> </li>
)} )}
renderInput={(props) => { renderInput={(props) => (
return (
<Input <Input
{...props} {...props}
label={t("label.postback")} label={t("label.postback")}
@ -257,7 +241,20 @@ export const PostbackInput = ({
...props.InputProps, ...props.InputProps,
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
{selectedValue?.type || t("label.postback")} <Chip
sx={{
p: "0",
m: "0 ",
fontSize: "12px",
minWidth: "75px",
maxHeight: "30px",
borderRadius: "16px 0 0 16px",
}}
style={{ padding: 0, margin: 0 }}
color="primary"
label={selectedValue?.type || t("label.postback")}
variant="role"
/>
</InputAdornment> </InputAdornment>
), ),
endAdornment: endAdornment:
@ -266,8 +263,7 @@ export const PostbackInput = ({
) : null, ) : null,
}} }}
/> />
); )}
}}
/> />
); );
}; };