diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json index 804ec95c..641b35ba 100644 --- a/frontend/public/locales/en/translation.json +++ b/frontend/public/locales/en/translation.json @@ -558,6 +558,12 @@ "manage_roles": "Manage Roles", "connect_with_sso": "Connect with SSO", "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", "toggle": "Toggle button" }, diff --git a/frontend/public/locales/fr/translation.json b/frontend/public/locales/fr/translation.json index 1b85dbfc..970ee76f 100644 --- a/frontend/public/locales/fr/translation.json +++ b/frontend/public/locales/fr/translation.json @@ -559,6 +559,12 @@ "manage_roles": "Gérer les rôles", "connect_with_sso": "Se connecter avec SSO", "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", "toggle": "Bouton de bascule" }, diff --git a/frontend/src/app-components/buttons/DropdownButton.tsx b/frontend/src/app-components/buttons/DropdownButton.tsx index 79dacb0f..cf205f76 100644 --- a/frontend/src/app-components/buttons/DropdownButton.tsx +++ b/frontend/src/app-components/buttons/DropdownButton.tsx @@ -32,6 +32,7 @@ interface AddPatternProps { label?: string; icon?: React.ReactNode; sx?: SxProps | undefined; + disabled?: boolean; } const DropdownButton: React.FC = ({ @@ -40,10 +41,13 @@ const DropdownButton: React.FC = ({ label = "Add", icon, sx, + disabled = false, }) => { const [anchorEl, setAnchorEl] = useState(null); const handleOpen = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); + if (!disabled) { + setAnchorEl(event.currentTarget); + } }; const handleClose = () => { setAnchorEl(null); @@ -61,6 +65,7 @@ const DropdownButton: React.FC = ({ onClick={handleOpen} startIcon={icon} endIcon={} + disabled={disabled} > {label} diff --git a/frontend/src/components/visual-editor/form/inputs/message/ButtonsInput.tsx b/frontend/src/components/visual-editor/form/inputs/message/ButtonsInput.tsx index 1b5e63a4..f1c4a0a5 100644 --- a/frontend/src/components/visual-editor/form/inputs/message/ButtonsInput.tsx +++ b/frontend/src/components/visual-editor/form/inputs/message/ButtonsInput.tsx @@ -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). */ -import { RemoveCircleOutline } from "@mui/icons-material"; +import { KeyboardReturn, Link, RemoveCircleOutline } from "@mui/icons-material"; import AddIcon from "@mui/icons-material/Add"; -import { Box, Button, Grid, IconButton } from "@mui/material"; -import { FC, Fragment, useEffect, useState } from "react"; +import { Box, Grid, IconButton } from "@mui/material"; +import { FC, Fragment, useEffect, useMemo, useState } from "react"; import { FieldPath } from "react-hook-form"; +import DropdownButton, { + DropdownButtonAction, +} from "@/app-components/buttons/DropdownButton"; import { useTranslate } from "@/hooks/useTranslate"; import { IBlockAttributes } from "@/types/block.types"; import { AnyButton, ButtonType } from "@/types/message.types"; @@ -40,11 +43,31 @@ const ButtonsInput: FC = ({ const [buttons, setButtons] = useState[]>( value.map((button) => createValueWithId(button)), ); - const addInput = () => { - setButtons([ - ...buttons, - createValueWithId({ type: ButtonType.postback, title: "", payload: "" }), - ]); + const actions: DropdownButtonAction[] = useMemo( + () => [ + { + icon: , + name: t("button.postback"), + defaultValue: { + type: ButtonType.postback, + title: "", + payload: "", + }, + }, + { + icon: , + 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 updatedButtons = [...buttons]; @@ -111,16 +134,14 @@ const ButtonsInput: FC = ({ ))} - + /> ); }; diff --git a/frontend/src/components/visual-editor/form/inputs/message/QuickRepliesInput.tsx b/frontend/src/components/visual-editor/form/inputs/message/QuickRepliesInput.tsx index c2b4ae60..39f45e67 100644 --- a/frontend/src/components/visual-editor/form/inputs/message/QuickRepliesInput.tsx +++ b/frontend/src/components/visual-editor/form/inputs/message/QuickRepliesInput.tsx @@ -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). */ -import { RemoveCircleOutline } from "@mui/icons-material"; +import { Abc, LocationOn, RemoveCircleOutline } from "@mui/icons-material"; import AddIcon from "@mui/icons-material/Add"; -import { Box, Button, Grid, IconButton } from "@mui/material"; -import { FC, Fragment, useEffect, useState } from "react"; +import { Box, Grid, IconButton } from "@mui/material"; +import { FC, Fragment, useEffect, useMemo, useState } from "react"; +import DropdownButton, { + DropdownButtonAction, +} from "@/app-components/buttons/DropdownButton"; import { useTranslate } from "@/hooks/useTranslate"; import { QuickReplyType, StdQuickReply } from "@/types/message.types"; import { ValueWithId, createValueWithId } from "@/utils/valueWithId"; @@ -31,16 +34,30 @@ const QuickRepliesInput: FC = ({ const { t } = useTranslate(); const [quickReplies, setQuickReplies] = useState< ValueWithId[] - >(value.map((quickReplie) => createValueWithId(quickReplie))); - const addInput = () => { - setQuickReplies([ - ...quickReplies, - createValueWithId({ - content_type: QuickReplyType.text, - title: "", - payload: "", - }), - ]); + >(value.map((quickReply) => createValueWithId(quickReply))); + const actions: DropdownButtonAction[] = useMemo( + () => [ + { + icon: , + name: t("button.text"), + defaultValue: { + content_type: QuickReplyType.text, + title: "", + payload: "", + }, + }, + { + icon: , + name: t("button.location"), + defaultValue: { + content_type: QuickReplyType.location, + }, + }, + ], + [t], + ); + const addInput = (defaultValue: StdQuickReply) => { + setQuickReplies([...quickReplies, createValueWithId(defaultValue)]); }; const removeInput = (index: number) => { const updatedQuickReplies = [...quickReplies]; @@ -104,16 +121,14 @@ const QuickRepliesInput: FC = ({ ))} - + /> ); };