2021-12-13 16:13:09 +00:00
|
|
|
import _ from 'lodash';
|
2022-03-30 09:21:22 +00:00
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
import { MultiSelect } from 'react-multi-select-component';
|
|
|
|
|
|
|
|
|
|
const ItemRenderer = ({ checked, option, onClick, disabled }) => (
|
|
|
|
|
<div className={`item-renderer ${disabled && 'disabled'}`}>
|
|
|
|
|
<input type="checkbox" onClick={onClick} checked={checked} tabIndex={-1} disabled={disabled} />
|
|
|
|
|
<span>{option.label}</span>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2021-04-14 17:01:34 +00:00
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
export const Multiselect = function Multiselect({
|
2022-03-10 12:00:33 +00:00
|
|
|
id,
|
|
|
|
|
component,
|
2021-04-30 06:31:32 +00:00
|
|
|
height,
|
2021-12-13 16:13:09 +00:00
|
|
|
properties,
|
|
|
|
|
styles,
|
|
|
|
|
exposedVariables,
|
|
|
|
|
setExposedVariable,
|
2023-12-11 09:41:00 +00:00
|
|
|
setExposedVariables,
|
2022-03-10 12:00:33 +00:00
|
|
|
onComponentClick,
|
2022-03-30 09:21:22 +00:00
|
|
|
darkMode,
|
2022-04-08 10:37:07 +00:00
|
|
|
fireEvent,
|
2023-01-24 11:52:35 +00:00
|
|
|
dataCy,
|
2021-12-13 16:13:09 +00:00
|
|
|
}) {
|
2022-03-30 09:21:22 +00:00
|
|
|
const { label, value, values, display_values, showAllOption } = properties;
|
2023-06-29 09:44:05 +00:00
|
|
|
const { borderRadius, visibility, disabledState, boxShadow } = styles;
|
2022-03-30 09:21:22 +00:00
|
|
|
const [selected, setSelected] = useState([]);
|
2023-09-01 09:52:24 +00:00
|
|
|
const [searched, setSearched] = useState('');
|
2022-03-30 09:21:22 +00:00
|
|
|
|
|
|
|
|
let selectOptions = [];
|
|
|
|
|
try {
|
|
|
|
|
selectOptions = [
|
|
|
|
|
...values.map((value, index) => {
|
|
|
|
|
return { label: display_values[index], value: value };
|
|
|
|
|
}),
|
|
|
|
|
];
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.log(err);
|
|
|
|
|
}
|
2021-04-30 06:31:32 +00:00
|
|
|
|
2021-12-13 16:13:09 +00:00
|
|
|
useEffect(() => {
|
|
|
|
|
let newValues = [];
|
2021-04-30 06:31:32 +00:00
|
|
|
|
2021-12-13 16:13:09 +00:00
|
|
|
if (_.intersection(values, value)?.length === value?.length) newValues = value;
|
2021-04-30 06:31:32 +00:00
|
|
|
|
2021-12-13 16:13:09 +00:00
|
|
|
setExposedVariable('values', newValues);
|
2022-03-30 09:21:22 +00:00
|
|
|
setSelected(selectOptions.filter((option) => newValues.includes(option.value)));
|
2021-12-13 16:13:09 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2023-03-20 06:08:25 +00:00
|
|
|
}, [JSON.stringify(values), JSON.stringify(display_values)]);
|
2021-04-30 06:31:32 +00:00
|
|
|
|
2021-12-13 16:13:09 +00:00
|
|
|
useEffect(() => {
|
|
|
|
|
setExposedVariable('values', value);
|
2022-03-30 09:21:22 +00:00
|
|
|
setSelected(selectOptions.filter((option) => value.includes(option.value)));
|
2021-12-13 16:13:09 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2023-03-20 06:08:25 +00:00
|
|
|
}, [JSON.stringify(value), JSON.stringify(display_values)]);
|
2021-09-21 13:48:28 +00:00
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
useEffect(() => {
|
2022-03-30 09:21:22 +00:00
|
|
|
if (value && !selected) {
|
|
|
|
|
setSelected(selectOptions.filter((option) => properties.value.includes(option.value)));
|
2021-12-13 16:13:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (JSON.stringify(exposedVariables.values) === '{}') {
|
2022-03-30 09:21:22 +00:00
|
|
|
setSelected(selectOptions.filter((option) => properties.value.includes(option.value)));
|
2021-12-13 16:13:09 +00:00
|
|
|
}
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2022-03-03 15:06:49 +00:00
|
|
|
}, []);
|
2021-12-13 16:13:09 +00:00
|
|
|
|
2022-04-08 10:37:07 +00:00
|
|
|
const onChangeHandler = (items) => {
|
|
|
|
|
setSelected(items);
|
2022-03-30 09:21:22 +00:00
|
|
|
setExposedVariable(
|
|
|
|
|
'values',
|
2022-04-08 10:37:07 +00:00
|
|
|
items.map((item) => item.value)
|
2023-09-01 08:25:03 +00:00
|
|
|
);
|
|
|
|
|
fireEvent('onSelect');
|
2022-04-08 10:37:07 +00:00
|
|
|
};
|
2021-04-30 06:31:32 +00:00
|
|
|
|
2023-09-01 08:25:03 +00:00
|
|
|
useEffect(() => {
|
2023-12-11 09:41:00 +00:00
|
|
|
const exposedVariables = {
|
|
|
|
|
selectOption: async function (value) {
|
|
|
|
|
if (
|
|
|
|
|
selectOptions.some((option) => option.value === value) &&
|
|
|
|
|
!selected.some((option) => option.value === value)
|
|
|
|
|
) {
|
|
|
|
|
const newSelected = [
|
|
|
|
|
...selected,
|
|
|
|
|
...selectOptions.filter(
|
|
|
|
|
(option) =>
|
|
|
|
|
option.value === value && !selected.map((selectedOption) => selectedOption.value).includes(value)
|
|
|
|
|
),
|
|
|
|
|
];
|
|
|
|
|
setSelected(newSelected);
|
|
|
|
|
setExposedVariable(
|
|
|
|
|
'values',
|
|
|
|
|
newSelected.map((item) => item.value)
|
|
|
|
|
);
|
|
|
|
|
fireEvent('onSelect');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
deselectOption: async function (value) {
|
|
|
|
|
if (
|
|
|
|
|
selectOptions.some((option) => option.value === value) &&
|
|
|
|
|
selected.some((option) => option.value === value)
|
|
|
|
|
) {
|
|
|
|
|
const newSelected = [
|
|
|
|
|
...selected.filter(function (item) {
|
|
|
|
|
return item.value !== value;
|
|
|
|
|
}),
|
|
|
|
|
];
|
|
|
|
|
setSelected(newSelected);
|
|
|
|
|
setExposedVariable(
|
|
|
|
|
'values',
|
|
|
|
|
newSelected.map((item) => item.value)
|
|
|
|
|
);
|
|
|
|
|
fireEvent('onSelect');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
clearSelections: async function () {
|
|
|
|
|
if (selected.length >= 1) {
|
|
|
|
|
setSelected([]);
|
|
|
|
|
setExposedVariable('values', []);
|
|
|
|
|
fireEvent('onSelect');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
setExposedVariables(exposedVariables);
|
2023-09-01 08:25:03 +00:00
|
|
|
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
|
}, [selected, setSelected]);
|
2022-07-19 10:06:00 +00:00
|
|
|
|
2023-09-01 09:52:24 +00:00
|
|
|
const filterOptions = (options, filter) => {
|
|
|
|
|
setSearched(filter);
|
|
|
|
|
|
|
|
|
|
if (searched !== filter) {
|
|
|
|
|
setExposedVariable('searchText', filter);
|
|
|
|
|
fireEvent('onSearchTextChanged');
|
|
|
|
|
}
|
|
|
|
|
if (!filter) return options;
|
|
|
|
|
|
|
|
|
|
return options.filter(
|
|
|
|
|
({ label, value }) => label != null && value != null && label.toLowerCase().includes(filter.toLowerCase())
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2021-04-30 06:31:32 +00:00
|
|
|
return (
|
2022-03-30 09:21:22 +00:00
|
|
|
<div
|
|
|
|
|
className="multiselect-widget row g-0"
|
2023-01-24 11:52:35 +00:00
|
|
|
data-cy={dataCy}
|
2022-03-30 09:21:22 +00:00
|
|
|
style={{ height, display: visibility ? '' : 'none' }}
|
|
|
|
|
onFocus={() => {
|
|
|
|
|
onComponentClick(this, id, component);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div className="col-auto my-auto d-flex align-items-center">
|
2022-08-04 14:46:53 +00:00
|
|
|
<label
|
|
|
|
|
style={{ marginRight: label ? '1rem' : '', marginBottom: 0 }}
|
2022-09-12 08:47:04 +00:00
|
|
|
className={`form-label py-1 ${darkMode ? 'text-light' : 'text-secondary'}`}
|
2022-08-04 14:46:53 +00:00
|
|
|
data-cy={`multiselect-label-${component.name.toLowerCase()}`}
|
|
|
|
|
>
|
2021-09-21 13:48:28 +00:00
|
|
|
{label}
|
|
|
|
|
</label>
|
2021-04-30 06:31:32 +00:00
|
|
|
</div>
|
2023-06-29 09:44:05 +00:00
|
|
|
<div className="col px-0 h-100" style={{ borderRadius: parseInt(borderRadius), boxShadow }}>
|
2022-03-30 09:21:22 +00:00
|
|
|
<MultiSelect
|
|
|
|
|
hasSelectAll={showAllOption ?? false}
|
2021-04-30 06:31:32 +00:00
|
|
|
options={selectOptions}
|
2022-03-30 09:21:22 +00:00
|
|
|
value={selected}
|
2022-04-08 10:37:07 +00:00
|
|
|
onChange={onChangeHandler}
|
2022-03-30 09:21:22 +00:00
|
|
|
labelledBy={'Select'}
|
|
|
|
|
disabled={disabledState}
|
2022-09-12 08:47:04 +00:00
|
|
|
className={`multiselect-box${darkMode ? ' dark dark-multiselectinput' : ''}`}
|
2022-03-30 09:21:22 +00:00
|
|
|
ItemRenderer={ItemRenderer}
|
2023-09-01 09:52:24 +00:00
|
|
|
filterOptions={filterOptions}
|
|
|
|
|
debounceDuration={0}
|
2021-04-30 06:31:32 +00:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2021-04-14 17:01:34 +00:00
|
|
|
};
|