fix: dropdown and multiselect component values on disabled and option text not truncating (#3089)
* Fixed dropdown component showing empty value and not showing dropdown when combobox is true * Fixed multiselect component showing empty value and not showing dropdown when combobox is true * Added disabled onChange on multiline and dropdown, with snapshot ignore * Fixed tooltip skip delay duration that made tooltip on Dropdown unusable * Fixed size of text inside dropdown and multiselect --------- Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
72ff6d3a58
commit
1336ae0772
5 changed files with 97 additions and 65 deletions
|
|
@ -5,6 +5,7 @@ import { ChangeEvent, useEffect, useRef, useState } from "react";
|
|||
import { DropDownComponentType } from "../../types/components";
|
||||
import { cn } from "../../utils/utils";
|
||||
import { default as ForwardedIconComponent } from "../genericIconComponent";
|
||||
import ShadTooltip from "../shadTooltipComponent";
|
||||
import { Button } from "../ui/button";
|
||||
import {
|
||||
Command,
|
||||
|
|
@ -47,15 +48,21 @@ export default function Dropdown({
|
|||
const value = event.target.value;
|
||||
const searchValues = fuse.search(value);
|
||||
const filtered = searchValues.map((search) => search.item);
|
||||
if (!filtered.includes(value) && combobox) filtered.push(value);
|
||||
if (!filtered.includes(value) && combobox && value) filtered.push(value);
|
||||
setFilteredOptions(value ? filtered : options);
|
||||
setCustomValue(value);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (disabled && value !== "") {
|
||||
onSelect("", undefined, true);
|
||||
}
|
||||
}, [disabled]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
const filtered = cloneDeep(options);
|
||||
if (customValue === value && combobox) {
|
||||
if (customValue === value && value && combobox) {
|
||||
filtered.push(customValue);
|
||||
}
|
||||
setFilteredOptions(filtered);
|
||||
|
|
@ -64,7 +71,7 @@ export default function Dropdown({
|
|||
|
||||
return (
|
||||
<>
|
||||
{Object.keys(options ?? [])?.length > 0 ? (
|
||||
{Object.keys(options ?? [])?.length > 0 || combobox ? (
|
||||
<>
|
||||
<Popover open={open} onOpenChange={children ? () => {} : setOpen}>
|
||||
{children ? (
|
||||
|
|
@ -131,32 +138,40 @@ export default function Dropdown({
|
|||
<CommandEmpty>No values found.</CommandEmpty>
|
||||
<CommandGroup defaultChecked={false}>
|
||||
{filteredOptions?.map((option, id) => (
|
||||
<CommandItem
|
||||
<ShadTooltip
|
||||
delayDuration={700}
|
||||
key={id}
|
||||
value={option}
|
||||
onSelect={(currentValue) => {
|
||||
onSelect(currentValue);
|
||||
setOpen(false);
|
||||
}}
|
||||
className="items-center truncate"
|
||||
data-testid={`${option}-${id ?? ""}-option`}
|
||||
content={option}
|
||||
>
|
||||
{customValue === option ? (
|
||||
<span className="text-muted-foreground">
|
||||
Text:
|
||||
</span>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{option}
|
||||
<ForwardedIconComponent
|
||||
name="Check"
|
||||
className={cn(
|
||||
"ml-auto h-4 w-4 text-primary",
|
||||
value === option ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
/>
|
||||
</CommandItem>
|
||||
<div>
|
||||
<CommandItem
|
||||
key={id}
|
||||
value={option}
|
||||
onSelect={(currentValue) => {
|
||||
onSelect(currentValue);
|
||||
setOpen(false);
|
||||
}}
|
||||
className="items-center overflow-hidden truncate"
|
||||
data-testid={`${option}-${id ?? ""}-option`}
|
||||
>
|
||||
{customValue === option ? (
|
||||
<span className="text-muted-foreground">
|
||||
Text:
|
||||
</span>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<span className="truncate">{option}</span>
|
||||
<ForwardedIconComponent
|
||||
name="Check"
|
||||
className={cn(
|
||||
"ml-auto h-4 w-4 shrink-0 text-primary",
|
||||
value === option ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
/>
|
||||
</CommandItem>
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default function InputListComponent({
|
|||
}: InputListComponentType): JSX.Element {
|
||||
useEffect(() => {
|
||||
if (disabled && value.length > 0 && value[0] !== "") {
|
||||
onChange([""]);
|
||||
onChange([""], undefined, true);
|
||||
}
|
||||
}, [disabled]);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useEffect, useRef, useState } from "react";
|
|||
import { MultiselectComponentType } from "../../types/components";
|
||||
import { cn } from "../../utils/utils";
|
||||
import { default as ForwardedIconComponent } from "../genericIconComponent";
|
||||
import ShadTooltip from "../shadTooltipComponent";
|
||||
import { Button } from "../ui/button";
|
||||
import {
|
||||
Command,
|
||||
|
|
@ -51,7 +52,7 @@ export default function MultiselectComponent({
|
|||
const fuse = onlySelected ? fuseValues : fuseOptions;
|
||||
const searchValues = fuse.search(v);
|
||||
let filtered: string[] = searchValues.map((search) => search.item);
|
||||
if (!filtered.includes(v) && combobox) filtered = [v, ...filtered];
|
||||
if (!filtered.includes(v) && combobox && v) filtered = [v, ...filtered];
|
||||
setFilteredOptions(
|
||||
v
|
||||
? filtered
|
||||
|
|
@ -61,6 +62,12 @@ export default function MultiselectComponent({
|
|||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (disabled && value.length > 0 && value[0] !== "") {
|
||||
onSelect([], undefined, true);
|
||||
}
|
||||
}, [disabled]);
|
||||
|
||||
useEffect(() => {
|
||||
searchRoleByTerm(searchValue);
|
||||
}, [onlySelected]);
|
||||
|
|
@ -72,7 +79,7 @@ export default function MultiselectComponent({
|
|||
useEffect(() => {
|
||||
setCustomValues(value.filter((v) => !defaultOptions.includes(v)) ?? []);
|
||||
setOptions([
|
||||
...value.filter((v) => !defaultOptions.includes(v)),
|
||||
...value.filter((v) => !defaultOptions.includes(v) && v),
|
||||
...defaultOptions,
|
||||
]);
|
||||
}, [value]);
|
||||
|
|
@ -87,7 +94,7 @@ export default function MultiselectComponent({
|
|||
|
||||
return (
|
||||
<>
|
||||
{Object.keys(options ?? [])?.length > 0 ? (
|
||||
{Object.keys(options ?? [])?.length > 0 || combobox ? (
|
||||
<>
|
||||
<Popover open={open} onOpenChange={children ? () => {} : setOpen}>
|
||||
{children ? (
|
||||
|
|
@ -171,38 +178,48 @@ export default function MultiselectComponent({
|
|||
<CommandEmpty>No values found.</CommandEmpty>
|
||||
<CommandGroup defaultChecked={false}>
|
||||
{filteredOptions?.map((option, id) => (
|
||||
<CommandItem
|
||||
<ShadTooltip
|
||||
delayDuration={700}
|
||||
key={id}
|
||||
value={option}
|
||||
onSelect={(currentValue) => {
|
||||
if (value.includes(currentValue)) {
|
||||
onSelect(value.filter((v) => v !== currentValue));
|
||||
} else {
|
||||
onSelect([...value, currentValue]);
|
||||
}
|
||||
}}
|
||||
className="items-center truncate"
|
||||
data-testid={`${option}-${id ?? ""}-option`}
|
||||
content={option}
|
||||
>
|
||||
{customValues.includes(option) ||
|
||||
searchValue === option ? (
|
||||
<span className="text-muted-foreground">
|
||||
Text:
|
||||
</span>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{option}
|
||||
<ForwardedIconComponent
|
||||
name="Check"
|
||||
className={cn(
|
||||
"ml-auto h-4 w-4 text-primary",
|
||||
value.includes(option)
|
||||
? "opacity-100"
|
||||
: "opacity-0",
|
||||
)}
|
||||
/>
|
||||
</CommandItem>
|
||||
<div>
|
||||
<CommandItem
|
||||
key={id}
|
||||
value={option}
|
||||
onSelect={(currentValue) => {
|
||||
if (value.includes(currentValue)) {
|
||||
onSelect(
|
||||
value.filter((v) => v !== currentValue),
|
||||
);
|
||||
} else {
|
||||
onSelect([...value, currentValue]);
|
||||
}
|
||||
}}
|
||||
className="items-center overflow-hidden truncate"
|
||||
data-testid={`${option}-${id ?? ""}-option`}
|
||||
>
|
||||
{customValues.includes(option) ||
|
||||
searchValue === option ? (
|
||||
<span className="text-muted-foreground">
|
||||
Text:
|
||||
</span>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<span className="truncate">{option}</span>
|
||||
<ForwardedIconComponent
|
||||
name="Check"
|
||||
className={cn(
|
||||
"ml-auto h-4 w-4 shrink-0 text-primary",
|
||||
value.includes(option)
|
||||
? "opacity-100"
|
||||
: "opacity-0",
|
||||
)}
|
||||
/>
|
||||
</CommandItem>
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default function ContextWrapper({ children }: { children: ReactNode }) {
|
|||
<BrowserRouter>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider>
|
||||
<TooltipProvider>
|
||||
<TooltipProvider skipDelayDuration={0}>
|
||||
<ReactFlowProvider>
|
||||
<ApiInterceptor />
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export type DropDownComponentType = {
|
|||
value: string;
|
||||
combobox?: boolean;
|
||||
options: string[];
|
||||
onSelect: (value: string) => void;
|
||||
onSelect: (value: string, dbValue?: boolean, snapshot?: boolean) => void;
|
||||
editNode?: boolean;
|
||||
id?: string;
|
||||
children?: ReactNode;
|
||||
|
|
@ -67,7 +67,7 @@ export type MultiselectComponentType = {
|
|||
value: string[];
|
||||
combobox?: boolean;
|
||||
options: string[];
|
||||
onSelect: (value: string[]) => void;
|
||||
onSelect: (value: string[], dbValue?: boolean, snapshot?: boolean) => void;
|
||||
editNode?: boolean;
|
||||
id?: string;
|
||||
children?: ReactNode;
|
||||
|
|
@ -96,7 +96,7 @@ export type ParameterComponentType = {
|
|||
};
|
||||
export type InputListComponentType = {
|
||||
value: string[];
|
||||
onChange: (value: string[]) => void;
|
||||
onChange: (value: string[], dbValue?: boolean, snapshot?: boolean) => void;
|
||||
disabled: boolean;
|
||||
editNode?: boolean;
|
||||
componentName?: string;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue