feat: new messages button

This commit is contained in:
hexastack 2024-12-09 16:10:43 +01:00
parent da25df6bb9
commit 1e2c758a5c
5 changed files with 91 additions and 38 deletions

View File

@ -558,6 +558,12 @@
"manage_roles": "Manage Roles", "manage_roles": "Manage Roles",
"connect_with_sso": "Connect with SSO", "connect_with_sso": "Connect with SSO",
"add_pattern": "New Trigger", "add_pattern": "New Trigger",
"postback": "Postback",
"url": "Url",
"add_button": "New Button",
"add_quick_reply": "New Quick Reply",
"text": "Text",
"location": "Location",
"mark_as_default": "Mark as Default", "mark_as_default": "Mark as Default",
"toggle": "Toggle button" "toggle": "Toggle button"
}, },

View File

@ -559,6 +559,12 @@
"manage_roles": "Gérer les rôles", "manage_roles": "Gérer les rôles",
"connect_with_sso": "Se connecter avec SSO", "connect_with_sso": "Se connecter avec SSO",
"add_pattern": "Ajouter un déclencheur", "add_pattern": "Ajouter un déclencheur",
"postback": "Valeur de retour",
"url": "Url",
"add_button": "Ajouter un bouton",
"add_quick_reply": "Ajouter une réponse rapide",
"text": "Texte",
"location": "Emplacement",
"mark_as_default": "Par Défaut", "mark_as_default": "Par Défaut",
"toggle": "Bouton de bascule" "toggle": "Bouton de bascule"
}, },

View File

@ -32,6 +32,7 @@ interface AddPatternProps {
label?: string; label?: string;
icon?: React.ReactNode; icon?: React.ReactNode;
sx?: SxProps<Theme> | undefined; sx?: SxProps<Theme> | undefined;
disabled?: boolean;
} }
const DropdownButton: React.FC<AddPatternProps> = ({ const DropdownButton: React.FC<AddPatternProps> = ({
@ -40,10 +41,13 @@ const DropdownButton: React.FC<AddPatternProps> = ({
label = "Add", label = "Add",
icon, icon,
sx, sx,
disabled = false,
}) => { }) => {
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null); const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
const handleOpen = (event: React.MouseEvent<HTMLElement>) => { const handleOpen = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget); if (!disabled) {
setAnchorEl(event.currentTarget);
}
}; };
const handleClose = () => { const handleClose = () => {
setAnchorEl(null); setAnchorEl(null);
@ -61,6 +65,7 @@ const DropdownButton: React.FC<AddPatternProps> = ({
onClick={handleOpen} onClick={handleOpen}
startIcon={icon} startIcon={icon}
endIcon={<ArrowDropDown />} endIcon={<ArrowDropDown />}
disabled={disabled}
> >
{label} {label}
</Button> </Button>

View File

@ -6,12 +6,15 @@
* 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 { 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, Button, Grid, IconButton } from "@mui/material"; import { Box, Grid, IconButton } from "@mui/material";
import { FC, Fragment, useEffect, useState } from "react"; import { FC, Fragment, useEffect, useMemo, useState } from "react";
import { FieldPath } from "react-hook-form"; import { FieldPath } from "react-hook-form";
import DropdownButton, {
DropdownButtonAction,
} from "@/app-components/buttons/DropdownButton";
import { useTranslate } from "@/hooks/useTranslate"; import { useTranslate } from "@/hooks/useTranslate";
import { IBlockAttributes } from "@/types/block.types"; import { IBlockAttributes } from "@/types/block.types";
import { AnyButton, ButtonType } from "@/types/message.types"; import { AnyButton, ButtonType } from "@/types/message.types";
@ -40,11 +43,31 @@ const ButtonsInput: FC<ButtonsInput> = ({
const [buttons, setButtons] = useState<ValueWithId<AnyButton>[]>( const [buttons, setButtons] = useState<ValueWithId<AnyButton>[]>(
value.map((button) => createValueWithId(button)), value.map((button) => createValueWithId(button)),
); );
const addInput = () => { const actions: DropdownButtonAction[] = useMemo(
setButtons([ () => [
...buttons, {
createValueWithId({ type: ButtonType.postback, title: "", payload: "" }), icon: <KeyboardReturn />,
]); name: t("button.postback"),
defaultValue: {
type: ButtonType.postback,
title: "",
payload: "",
},
},
{
icon: <Link />,
name: t("button.url"),
defaultValue: {
type: ButtonType.web_url,
title: "",
url: "",
},
},
],
[t],
);
const addInput = (defaultValue: AnyButton) => {
setButtons([...buttons, createValueWithId(defaultValue)]);
}; };
const removeInput = (index: number) => { const removeInput = (index: number) => {
const updatedButtons = [...buttons]; const updatedButtons = [...buttons];
@ -111,16 +134,14 @@ const ButtonsInput: FC<ButtonsInput> = ({
</Fragment> </Fragment>
))} ))}
</Grid> </Grid>
<Button <DropdownButton
variant="contained"
color="primary"
onClick={addInput}
startIcon={<AddIcon />}
sx={{ m: 1, float: "right" }} sx={{ m: 1, float: "right" }}
label={t("button.add_button")}
actions={actions}
onClick={(action) => addInput(action.defaultValue)}
icon={<AddIcon />}
disabled={buttons.length >= maxInput} disabled={buttons.length >= maxInput}
> />
{t("button.add")}
</Button>
</Box> </Box>
); );
}; };

View File

@ -6,11 +6,14 @@
* 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 { RemoveCircleOutline } from "@mui/icons-material"; import { Abc, LocationOn, RemoveCircleOutline } from "@mui/icons-material";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import { Box, Button, Grid, IconButton } from "@mui/material"; import { Box, Grid, IconButton } from "@mui/material";
import { FC, Fragment, useEffect, useState } from "react"; import { FC, Fragment, useEffect, useMemo, useState } from "react";
import DropdownButton, {
DropdownButtonAction,
} from "@/app-components/buttons/DropdownButton";
import { useTranslate } from "@/hooks/useTranslate"; import { useTranslate } from "@/hooks/useTranslate";
import { QuickReplyType, StdQuickReply } from "@/types/message.types"; import { QuickReplyType, StdQuickReply } from "@/types/message.types";
import { ValueWithId, createValueWithId } from "@/utils/valueWithId"; import { ValueWithId, createValueWithId } from "@/utils/valueWithId";
@ -31,16 +34,30 @@ const QuickRepliesInput: FC<QuickRepliesInput> = ({
const { t } = useTranslate(); const { t } = useTranslate();
const [quickReplies, setQuickReplies] = useState< const [quickReplies, setQuickReplies] = useState<
ValueWithId<StdQuickReply>[] ValueWithId<StdQuickReply>[]
>(value.map((quickReplie) => createValueWithId(quickReplie))); >(value.map((quickReply) => createValueWithId(quickReply)));
const addInput = () => { const actions: DropdownButtonAction[] = useMemo(
setQuickReplies([ () => [
...quickReplies, {
createValueWithId({ icon: <Abc />,
content_type: QuickReplyType.text, name: t("button.text"),
title: "", defaultValue: {
payload: "", content_type: QuickReplyType.text,
}), title: "",
]); payload: "",
},
},
{
icon: <LocationOn />,
name: t("button.location"),
defaultValue: {
content_type: QuickReplyType.location,
},
},
],
[t],
);
const addInput = (defaultValue: StdQuickReply) => {
setQuickReplies([...quickReplies, createValueWithId(defaultValue)]);
}; };
const removeInput = (index: number) => { const removeInput = (index: number) => {
const updatedQuickReplies = [...quickReplies]; const updatedQuickReplies = [...quickReplies];
@ -104,16 +121,14 @@ const QuickRepliesInput: FC<QuickRepliesInput> = ({
</Fragment> </Fragment>
))} ))}
</Grid> </Grid>
<Button <DropdownButton
variant="contained"
color="primary"
onClick={addInput}
startIcon={<AddIcon />}
sx={{ marginTop: 2, float: "right" }} sx={{ marginTop: 2, float: "right" }}
label={t("button.add_quick_reply")}
actions={actions}
onClick={(action) => addInput(action.defaultValue)}
icon={<AddIcon />}
disabled={quickReplies.length > 10} disabled={quickReplies.length > 10}
> />
{t("button.add")}
</Button>
</Box> </Box>
); );
}; };