Merge pull request #460 from Hexastack/fix/buttons-display

fix: Buttons display in the list/carousel block form
This commit is contained in:
Med Marrouchi 2024-12-19 06:45:54 +01:00 committed by GitHub
commit db9bc43560
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 93 additions and 106 deletions

View File

@ -41,7 +41,7 @@ export const ToggleableInput = forwardRef(
}, [readOnlyValue, isDisabled, defaultValue]); }, [readOnlyValue, isDisabled, defaultValue]);
return ( return (
<Box display="flex"> <Box display="flex" flex={1}>
<Switch <Switch
onChange={() => { onChange={() => {
const newIsDisabled = !isDisabled; const newIsDisabled = !isDisabled;

View File

@ -166,7 +166,7 @@ const ListMessageForm = () => {
</ContentItem> </ContentItem>
</Grid> </Grid>
<Grid item xs={1}> <Grid item xs={1}>
<Divider orientation="vertical" sx={{ margin: "2rem" }} /> <Divider orientation="vertical" sx={{ marginX: "2rem" }} />
</Grid> </Grid>
<Grid item xs={6}> <Grid item xs={6}>
<FormLabel component="h4" sx={{ marginBottom: "1rem" }}> <FormLabel component="h4" sx={{ marginBottom: "1rem" }}>
@ -278,7 +278,7 @@ const ListMessageForm = () => {
/> />
</ContentItem> </ContentItem>
</Grid> </Grid>
<ContentItem> <ContentItem width="100%">
<FormSectionTitle title={t("label.buttons")} Icon={ButtonsIcon} /> <FormSectionTitle title={t("label.buttons")} Icon={ButtonsIcon} />
<Controller <Controller
name="options.content.buttons" name="options.content.buttons"

View File

@ -6,7 +6,7 @@
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/ */
import { Grid } from "@mui/material"; import { Box } from "@mui/material";
import { FC } from "react"; import { FC } from "react";
import { FieldPath, useFormContext } from "react-hook-form"; import { FieldPath, useFormContext } from "react-hook-form";
@ -48,88 +48,86 @@ const ButtonInput: FC<ButtonInputProps> = ({
} = useFormContext<IBlockAttributes>(); } = useFormContext<IBlockAttributes>();
return ( return (
<> <Box display="flex" flex={1} flexGrow={1} gap={2}>
<Grid item xs={5}> <Input
fullWidth={false}
required
label={t("label.title")}
value={button.title}
sx={{ flex: 1 }}
inputProps={{
maxLength: 20,
}}
{...register(buildFieldPath(fieldPath, idx, "title"), {
required: t("message.title_is_required"),
})}
onChange={(e) => {
onChange({ ...button, title: e.target.value });
}}
error={!!errors.message?.["buttons"]?.[idx]?.title}
helperText={
errors.message?.["buttons"]?.[idx]?.title?.message ||
(button.title.length === 20
? t("message.title_length_exceeded")
: null)
}
/>
{button.type === ButtonType.postback ? (
<ToggleableInput
defaultValue={button.payload}
readOnlyValue={button.title}
{...register(buildFieldPath(fieldPath, idx, "payload"), {
validate: {
required: (value) => {
if (disablePayload || value) {
return true;
}
return t("message.payload_is_required");
},
},
})}
onChange={(payload) =>
onChange({
...button,
payload,
})
}
disabled={disablePayload}
error={!!errors.message?.["buttons"]?.[idx]?.payload}
helperText={errors.message?.["buttons"]?.[idx]?.payload?.message}
/>
) : (
<Input <Input
fullWidth
required required
placeholder={t("label.title")} type="url"
value={button.title} label={t("label.url")}
inputProps={{ value={button.url}
maxLength: 20, sx={{ flex: 1 }}
}} {...register(buildFieldPath(fieldPath, idx, "url"), {
{...register(buildFieldPath(fieldPath, idx, "title"), { validate: {
required: t("message.title_is_required"), required: (value) => {
if (
button.type === ButtonType.web_url &&
(disablePayload || value)
) {
return true;
}
return t("message.url_is_required");
},
},
...rules.url,
})} })}
onChange={(e) => { onChange={(e) => {
onChange({ ...button, title: e.target.value }); onChange({ ...button, url: e.target.value });
}} }}
error={!!errors.message?.["buttons"]?.[idx]?.title} disabled={disablePayload}
helperText={ error={!!errors.message?.["buttons"]?.[idx]?.url}
errors.message?.["buttons"]?.[idx]?.title?.message || helperText={errors.message?.["buttons"]?.[idx]?.url?.message}
(button.title.length === 20
? t("message.title_length_exceeded")
: null)
}
/> />
</Grid> )}
<Grid item xs={6}> </Box>
{button.type === ButtonType.postback ? (
<ToggleableInput
defaultValue={button.payload}
readOnlyValue={button.title}
{...register(buildFieldPath(fieldPath, idx, "payload"), {
validate: {
required: (value) => {
if (disablePayload || value) {
return true;
}
return t("message.payload_is_required");
},
},
})}
onChange={(payload) =>
onChange({
...button,
payload,
})
}
disabled={disablePayload}
error={!!errors.message?.["buttons"]?.[idx]?.payload}
helperText={errors.message?.["buttons"]?.[idx]?.payload?.message}
/>
) : (
<Input
required
type="ur"
placeholder="URL"
value={button.url}
{...register(buildFieldPath(fieldPath, idx, "url"), {
validate: {
required: (value) => {
if (
button.type === ButtonType.web_url &&
(disablePayload || value)
) {
return true;
}
return t("message.url_is_required");
},
},
...rules.url,
})}
onChange={(e) => {
onChange({ ...button, url: e.target.value });
}}
disabled={disablePayload}
error={!!errors.message?.["buttons"]?.[idx]?.url}
helperText={errors.message?.["buttons"]?.[idx]?.url?.message}
/>
)}
</Grid>
</>
); );
}; };

View File

@ -8,8 +8,8 @@
import { KeyboardReturn, Link, RemoveCircleOutline } from "@mui/icons-material"; import { KeyboardReturn, Link, RemoveCircleOutline } from "@mui/icons-material";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import { Box, Grid, IconButton } from "@mui/material"; import { Box, IconButton } from "@mui/material";
import { FC, Fragment, useEffect, useMemo, useState } from "react"; import { FC, useEffect, useMemo, useState } from "react";
import { FieldPath } from "react-hook-form"; import { FieldPath } from "react-hook-form";
import DropdownButton, { import DropdownButton, {
@ -96,19 +96,10 @@ const ButtonsInput: FC<ButtonsInput> = ({
}, [buttons]); }, [buttons]);
return ( return (
<Box> <Box display="flex" flexDirection="column">
<Grid container spacing={2}> <Box display="flex" flexDirection="column">
<Grid item xs={5}>
{t("label.title")}
</Grid>
<Grid item xs={6}>
{t("label.payload")} / {t("label.url")}
</Grid>
<Grid item xs={1}>
&nbsp;
</Grid>
{buttons.map(({ value, id }, idx) => ( {buttons.map(({ value, id }, idx) => (
<Fragment key={id}> <Box display="flex" flex={1} mt={2} key={id}>
<ButtonInput <ButtonInput
fieldPath={fieldPath} fieldPath={fieldPath}
idx={idx} idx={idx}
@ -116,20 +107,18 @@ const ButtonsInput: FC<ButtonsInput> = ({
onChange={updateInput(idx)} onChange={updateInput(idx)}
disablePayload={disablePayload} disablePayload={disablePayload}
/> />
<Grid item xs={1}> <IconButton
<IconButton color="error"
color="error" onClick={() => removeInput(idx)}
onClick={() => removeInput(idx)} disabled={buttons.length <= minInput}
disabled={buttons.length <= minInput} >
> <RemoveCircleOutline />
<RemoveCircleOutline /> </IconButton>
</IconButton> </Box>
</Grid>
</Fragment>
))} ))}
</Grid> </Box>
<DropdownButton <DropdownButton
sx={{ m: 1, float: "right", padding: "16px" }} sx={{ alignSelf: "end", marginTop: 2 }}
label={t("button.add_button")} label={t("button.add_button")}
actions={actions} actions={actions}
onClick={(action) => addInput(action.defaultValue)} onClick={(action) => addInput(action.defaultValue)}