update: nlp select pattern v0.0.1

This commit is contained in:
yassinedorbozgithub 2024-11-25 19:01:35 +01:00
parent 5cda7ae2c6
commit eba199c7d7
2 changed files with 144 additions and 105 deletions

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 { RemoveOutlined } from "@mui/icons-material"; import { Cancel } from "@mui/icons-material";
import { import {
Box, Box,
CircularProgress, CircularProgress,
@ -27,10 +27,13 @@ import { EntityType, Format } from "@/services/types";
import { NlpPattern } from "@/types/block.types"; import { NlpPattern } from "@/types/block.types";
import { INlpEntity } from "@/types/nlp-entity.types"; import { INlpEntity } from "@/types/nlp-entity.types";
type NlpPatternSelectProps = {}; type NlpPatternSelectProps = { patterns: NlpPattern[]; onChange: any };
const NlpPatternSelect = ({}: NlpPatternSelectProps, ref) => { const NlpPatternSelect = (
const [selected, setSelected] = useState<NlpPattern[]>([]); { patterns, onChange }: NlpPatternSelectProps,
ref,
) => {
const [selected, setSelected] = useState<NlpPattern[]>(patterns);
const theme = useTheme(); const theme = useTheme();
const { t } = useTranslate(); const { t } = useTranslate();
const { onSearch, searchPayload } = useSearch<INlpEntity>({ const { onSearch, searchPayload } = useSearch<INlpEntity>({
@ -69,12 +72,6 @@ const NlpPatternSelect = ({}: NlpPatternSelectProps, ref) => {
} }
const handleNlpValueChange = (entity: INlpEntity, valueId: string) => { const handleNlpValueChange = (entity: INlpEntity, valueId: string) => {
const value = getNlpValueFromCache(valueId);
if (!value) {
throw new Error("Unable to find nlp value in cache");
}
const newSelection = [...selected]; const newSelection = [...selected];
const update = newSelection.find(({ entity: e }) => e === entity.name); const update = newSelection.find(({ entity: e }) => e === entity.name);
@ -82,23 +79,32 @@ const NlpPatternSelect = ({}: NlpPatternSelectProps, ref) => {
throw new Error("Unable to find nlp entity"); throw new Error("Unable to find nlp entity");
} }
if (value.id === entity.id) { if (valueId === entity.id) {
update.match = "entity"; update.match = "entity";
update.value = entity.name; update.value = entity.name;
} else { } else {
const value = getNlpValueFromCache(valueId);
if (!value) {
throw new Error("Unable to find nlp value in cache");
}
update.match = "value"; update.match = "value";
update.value = value.value; update.value = value.value;
} }
onChange(undefined, newSelection);
}; };
const defaultValue =
options.filter(({ name }) =>
selected.find(({ entity: entityName }) => entityName === name),
) || {};
return ( return (
<Autocomplete <Autocomplete
ref={ref} ref={ref}
size="medium" size="medium"
disabled={options.length === 0} disabled={options.length === 0}
defaultValue={options.filter(({ name }) => defaultValue={defaultValue}
selected.find(({ entity: entityName }) => entityName === name),
)}
multiple={true} multiple={true}
options={options} options={options}
onChange={handleNlpEntityChange} onChange={handleNlpEntityChange}
@ -136,92 +142,121 @@ const NlpPatternSelect = ({}: NlpPatternSelectProps, ref) => {
isOptionEqualToValue={(option, value) => option.id === value.id} isOptionEqualToValue={(option, value) => option.id === value.id}
freeSolo={false} freeSolo={false}
loading={isLoading} loading={isLoading}
renderTags={(entities, getTagProps) => ( renderTags={(entities, getTagProps) => {
<Box return (
sx={{ <Box
display: "flex", sx={{
flexWrap: "wrap", display: "flex",
gap: 0.5, flexWrap: "wrap",
}} gap: 0.5,
> }}
{entities.map((entity, index) => { >
const { key, onDelete } = getTagProps({ index }); {entities.map((entity, index) => {
const handleChange = ( const { key, onDelete } = getTagProps({ index });
event: SyntheticEvent<Element, Event>, const handleChange = (
valueId: string, event: SyntheticEvent<Element, Event>,
) => { valueId: string,
handleNlpValueChange(entity, valueId); ) => {
}; handleNlpValueChange(entity, valueId);
};
const selected = (
Array.isArray(patterns)
? patterns?.find((e) => e.entity === entity.name)
: {}
) as NlpPattern;
return ( return (
<Autocomplete <Autocomplete
size="small" size="small"
options={[entity.id].concat(entity.values)} defaultValue={selected?.value || ""}
multiple={false} options={[entity.id].concat(entity.values)}
key={key} multiple={false}
getOptionLabel={(option) => key={key}
option getOptionLabel={(option) => {
? getNlpValueFromCache(option)?.value || "-" const nlpValueCache = getNlpValueFromCache(option);
: t("label.any")
} if (nlpValueCache) {
disableClearable return nlpValueCache?.value;
popupIcon={false} }
onChange={handleChange}
sx={{ if (selected?.entity === option || option === entity.id) {
minWidth: 50, return t("label.any");
padding: 0, }
".MuiAutocomplete-input": {
minWidth: "100px !important", return option;
}, }}
"& .MuiOutlinedInput-root": { disableClearable
paddingRight: "2rem !important", popupIcon={false}
"&.MuiInputBase-sizeSmall": { onChange={handleChange}
padding: "0 !important", sx={{
minWidth: 50,
padding: 0,
".MuiAutocomplete-input": {
minWidth: "100px !important",
}, },
}, "& .MuiOutlinedInput-root": {
}} paddingRight: "2rem !important",
renderInput={(props) => ( "&.MuiInputBase-sizeSmall": {
<Input padding: "0 6px 0 0 !important",
{...props} },
sx={{ padding: 0, overflow: "hidden" }} },
// onChange={(e) => onSearch(e.target.value)} }}
InputProps={{ renderInput={(props) => (
...props.InputProps, <Input
startAdornment: ( {...props}
<InputAdornment InputProps={{
position="start" ...props.InputProps,
sx={{ readOnly: true,
padding: "0 1rem", sx: {
height: "100%", overflow: "hidden",
backgroundColor: theme.palette.grey[200], },
}} startAdornment: (
> <IconButton>
{entity.name} <InputAdornment
</InputAdornment> position="start"
), sx={{
endAdornment: ( padding: "0 1rem",
<InputAdornment position="end"> height: "100%",
{isLoading ? ( backgroundColor: theme.palette.grey[200],
<CircularProgress color="inherit" size={20} /> }}
) : (
<IconButton
onClick={onDelete}
edge="end"
size="small"
> >
<RemoveOutlined /> {entity.name}
</IconButton> </InputAdornment>
)} </IconButton>
</InputAdornment> ),
), endAdornment: (
}} <InputAdornment position="end">
/> {isLoading ? (
)} <CircularProgress color="inherit" size={20} />
/> ) : (
); <IconButton
})} onClick={(e) => {
</Box> onDelete(e);
)}
onChange(
undefined,
patterns.filter(
(p) => p.entity !== entity.name,
),
);
}}
edge="end"
size="small"
>
<Cancel htmlColor={theme.palette.grey[500]} />
</IconButton>
)}
</InputAdornment>
),
}}
/>
)}
/>
);
})}
</Box>
);
}}
renderInput={(props) => ( renderInput={(props) => (
<Input <Input
{...props} {...props}

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 { Box, Grid, MenuItem, TextFieldProps, Typography } from "@mui/material"; import { Grid, MenuItem, TextFieldProps } from "@mui/material";
import { FC, useEffect, useState } from "react"; import { FC, useEffect, useState } from "react";
import { RegisterOptions, useFormContext } from "react-hook-form"; import { RegisterOptions, useFormContext } from "react-hook-form";
@ -14,7 +14,6 @@ import AutoCompleteEntitySelect from "@/app-components/inputs/AutoCompleteEntity
import { Input } from "@/app-components/inputs/Input"; import { Input } from "@/app-components/inputs/Input";
import NlpPatternSelect from "@/app-components/inputs/NlpPatternSelect"; import NlpPatternSelect from "@/app-components/inputs/NlpPatternSelect";
import { RegexInput } from "@/app-components/inputs/RegexInput"; import { RegexInput } from "@/app-components/inputs/RegexInput";
import { useGetFromCache } from "@/hooks/crud/useGet";
import { useTranslate } from "@/hooks/useTranslate"; import { useTranslate } from "@/hooks/useTranslate";
import { EntityType, Format } from "@/services/types"; import { EntityType, Format } from "@/services/types";
import { import {
@ -26,8 +25,6 @@ import {
PayloadPattern, PayloadPattern,
} from "@/types/block.types"; } from "@/types/block.types";
import { IMenuItem } from "@/types/menu.types"; import { IMenuItem } from "@/types/menu.types";
import { INlpEntity } from "@/types/nlp-entity.types";
import { INlpValue } from "@/types/nlp-value.types";
import { ContentPostbackInput } from "./ContentPostbackInput"; import { ContentPostbackInput } from "./ContentPostbackInput";
import { PostbackInput } from "./PostbackInput"; import { PostbackInput } from "./PostbackInput";
@ -72,7 +69,7 @@ const PatternInput: FC<PatternInputProps> = ({
register, register,
formState: { errors }, formState: { errors },
} = useFormContext<IBlockAttributes>(); } = useFormContext<IBlockAttributes>();
const getNlpEntityFromCache = useGetFromCache(EntityType.NLP_ENTITY); // const getNlpEntityFromCache = useGetFromCache(EntityType.NLP_ENTITY);
const [pattern, setPattern] = useState<Pattern>(value); const [pattern, setPattern] = useState<Pattern>(value);
const [patternType, setPatternType] = useState<PatternType>(getType(value)); const [patternType, setPatternType] = useState<PatternType>(getType(value));
const types = [ const types = [
@ -148,8 +145,15 @@ const PatternInput: FC<PatternInputProps> = ({
</Input> </Input>
</Grid> </Grid>
<Grid item xs={9}> <Grid item xs={9}>
{patternType === "nlp" && <NlpPatternSelect />} {patternType === "nlp" && (
{patternType === "nlp" ? ( <NlpPatternSelect
patterns={pattern as NlpPattern[]}
onChange={(_e, data) => {
setPattern(data);
}}
/>
)}
{/* {patternType === "nlp" ? (
<AutoCompleteEntitySelect<INlpValue, "value"> <AutoCompleteEntitySelect<INlpValue, "value">
value={(pattern as NlpPattern[]).map((v) => value={(pattern as NlpPattern[]).map((v) =>
"value" in v && v.value ? v.value : v.entity, "value" in v && v.value ? v.value : v.entity,
@ -225,7 +229,7 @@ const PatternInput: FC<PatternInputProps> = ({
}, [] as INlpValue[]); }, [] as INlpValue[]);
}} }}
/> />
) : null} ) : null} */}
{patternType === "menu" ? ( {patternType === "menu" ? (
<AutoCompleteEntitySelect<IMenuItem, "title", false> <AutoCompleteEntitySelect<IMenuItem, "title", false>
value={pattern ? (pattern as PayloadPattern).value : null} value={pattern ? (pattern as PayloadPattern).value : null}