try to customise multi select dropdown component with Ids#187
try to customise multi select dropdown component with Ids#187kevinleeTCA wants to merge 3 commits intoembeddable-hq:mainfrom
Conversation
kevinleeTCA
commented
Jan 9, 2025
| { | ||
| name: 'id', | ||
| type: 'dimension', | ||
| label: 'ID', | ||
| config: { | ||
| dataset: 'ds' | ||
| }, | ||
| category: 'Dropdown ids' | ||
| }, |
There was a problem hiding this comment.
This is where we add the id dimension that later will be linked to a variable to filter other charts data using id (built in index)
| // { | ||
| // name: 'defaultValue', | ||
| // type: 'string', | ||
| // array: true, | ||
| // label: 'Default value', | ||
| // category: 'Pre-configured variables' | ||
| // }, |
| ...inputs, | ||
| options: loadData({ | ||
| from: inputs.ds, | ||
| dimensions: inputs.property ? [inputs.property, inputs.id] : [], |
| return { | ||
| value: value.length ? value : Value.noFilter(), | ||
| id: id.length ? id : Value.noFilter() | ||
| }; |
There was a problem hiding this comment.
This is where we would like to capture an object (instead of value string) to be able to assign the id to a variable used for filters
| export type EventPayload = { | ||
| value: string; | ||
| id: string; | ||
| } |
There was a problem hiding this comment.
Now the event payload should have an object type instead of string
| className?: string; | ||
| options: DataResponse; | ||
| unclearable?: boolean; | ||
| onChange: (v: EventPayload[]) => void; |
There was a problem hiding this comment.
and onChange should capture event payload containing both value and id
| const set = useCallback( | ||
| (newValue: EventPayload) => { | ||
| performSearch(''); | ||
|
|
||
| let newValues: EventPayload[] = []; | ||
|
|
||
| if (newValue.value !== '') { | ||
| newValues = value || []; | ||
| if (newValues?.includes(newValue)) { | ||
| newValues = newValues.filter((v) => v.value !== newValue.value); | ||
| } else { | ||
| newValues = [...newValues, newValue]; | ||
| } | ||
| } | ||
|
|
||
| props.onChange(newValues); | ||
| setValue(newValues); | ||
| setServerSearch((s) => ({ ...s, [props.searchProperty || 'search']: '' })); | ||
| clearTimeout(debounce); | ||
| }, |
…anilla-components into multiSelectDropdownWithIds
There was a problem hiding this comment.
PR Summary
This PR introduces a new MultiSelectDropdownWithIds component that extends the existing dropdown functionality to support both display values and corresponding IDs, enabling more complex data relationships in selections.
- The
EventPayloadtype in/src/components/vanilla/controls/MultiSelectDropdownWithIds/index.tsxneeds proper handling in theset()function for ID field management - Global
debouncevariable in/src/components/vanilla/controls/MultiSelectDropdownWithIds/index.tsxshould be moved into component scope to prevent cross-instance interference - The
includes()check in the list rendering logic needs to be updated to properly compare objects with both value and ID fields - The component adds new
iddimension input in.emb.tsto load corresponding IDs alongside property values
💡 (1/5) You can manually trigger the bot by mentioning @greptileai in a comment!
2 file(s) reviewed, 5 comment(s)
Edit PR Review Bot Settings | Greptile
| ...inputs, | ||
| options: loadData({ | ||
| from: inputs.ds, | ||
| dimensions: inputs.property ? [inputs.property, inputs.id] : [], |
There was a problem hiding this comment.
logic: No check for inputs.id before including it in dimensions array. Could cause runtime issues if id field not configured.
| dimensions: inputs.property ? [inputs.property, inputs.id] : [], | |
| dimensions: inputs.property && inputs.id ? [inputs.property, inputs.id] : [], |
| options: loadData({ | ||
| from: inputs.ds, | ||
| dimensions: inputs.property ? [inputs.property, inputs.id] : [], | ||
| limit: inputs.limit || 1000, |
There was a problem hiding this comment.
style: Default limit of 1000 differs from meta default of 100. Should be consistent.
| if (newValues?.includes(newValue)) { | ||
| newValues = newValues.filter((v) => v.value !== newValue.value); |
There was a problem hiding this comment.
logic: Array.includes() won't work correctly for object comparison. Need to use array.find() with proper value/id comparison
| if (newValues?.includes(newValue)) { | |
| newValues = newValues.filter((v) => v.value !== newValue.value); | |
| if (newValues?.find(v => v.value === newValue.value && v.id === newValue.id)) { | |
| newValues = newValues.filter((v) => v.value !== newValue.value); |
| key={i} | ||
| onClick={() => { | ||
| setTriggerBlur(false); | ||
| set(o[props.property?.name || ''] || ''); |
There was a problem hiding this comment.
logic: Missing ID field in set() call. Should be set({value: o[props.property?.name || ''], id: o.id}) to properly handle both value and ID
| set(o[props.property?.name || ''] || ''); | |
| set({value: o[props.property?.name || ''] || '', id: o.id}); |
|
|
||
| type Record = { [p: string]: string }; | ||
|
|
||
| let debounce: number | undefined = undefined; |
There was a problem hiding this comment.
style: Global debounce variable will cause issues with multiple component instances. Move inside component using useRef
| let debounce: number | undefined = undefined; | |
| const debounce = useRef<number>(); |



