multi select box
This commit is contained in:
BIN
app/.DS_Store
vendored
BIN
app/.DS_Store
vendored
Binary file not shown.
BIN
app/views/.DS_Store
vendored
BIN
app/views/.DS_Store
vendored
Binary file not shown.
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.295faf6a.css",
|
||||
"main.js": "/static/js/main.8e7190e1.js",
|
||||
"main.css": "/static/css/main.3078ab9c.css",
|
||||
"main.js": "/static/js/main.d4629ce4.js",
|
||||
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
|
||||
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
|
||||
"index.html": "/index.html",
|
||||
"main.295faf6a.css.map": "/static/css/main.295faf6a.css.map",
|
||||
"main.8e7190e1.js.map": "/static/js/main.8e7190e1.js.map",
|
||||
"main.3078ab9c.css.map": "/static/css/main.3078ab9c.css.map",
|
||||
"main.d4629ce4.js.map": "/static/js/main.d4629ce4.js.map",
|
||||
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.295faf6a.css",
|
||||
"static/js/main.8e7190e1.js"
|
||||
"static/css/main.3078ab9c.css",
|
||||
"static/js/main.d4629ce4.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.8e7190e1.js"></script><link href="/static/css/main.295faf6a.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.d4629ce4.js"></script><link href="/static/css/main.3078ab9c.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/views/static/css/main.3078ab9c.css.map
Normal file
1
app/views/static/css/main.3078ab9c.css.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
app/views/static/js/main.d4629ce4.js
Normal file
3
app/views/static/js/main.d4629ce4.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
client/.DS_Store
vendored
BIN
client/.DS_Store
vendored
Binary file not shown.
@@ -2477,4 +2477,167 @@ input[type="checkbox"] {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* MultiSelectDropdown */
|
||||
.multi-select-dropdown {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__control {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
min-height: 45px;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__control:hover {
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__control--open {
|
||||
border-color: #2684FF;
|
||||
box-shadow: 0 0 0 1px #2684FF;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__value-container {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__placeholder {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__tags {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: #E8F0FE;
|
||||
color: #1A73E8;
|
||||
border-radius: 4px;
|
||||
padding: 2px 6px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__tag-remove {
|
||||
margin-left: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1A73E8;
|
||||
flex-shrink: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__tag-remove:hover {
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 8px;
|
||||
padding-top: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 4px);
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 999;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__search-container {
|
||||
padding: 10px 14px;
|
||||
border-bottom: 1px solid #eee;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__search {
|
||||
display: block;
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
padding: 8px 10px !important;
|
||||
border: 1px solid #ddd !important;
|
||||
border-radius: 6px !important;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__search:focus {
|
||||
border-color: #2684FF !important;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__select-all {
|
||||
border-bottom: 1px solid #eee;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__options-list {
|
||||
max-height: 220px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 14px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__option:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__option--selected {
|
||||
background: #EBF5FF;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
accent-color: #2684FF;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.multi-select-dropdown__no-options {
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
@@ -26,7 +26,8 @@ import {
|
||||
DIET_TEXTURE, DIET_TEXTURE_TEXT,
|
||||
TRANSPORTATION_TYPE, TRANSPORTATION_TYPE_TEXT,
|
||||
YES_NO, YES_NO_TEXT,
|
||||
PREFERRED_TEXT_LANGUAGE, PREFERRED_TEXT_LANGUAGE_TEXT
|
||||
PREFERRED_TEXT_LANGUAGE, PREFERRED_TEXT_LANGUAGE_TEXT,
|
||||
MultiSelectDropdown
|
||||
} from "../../shared";
|
||||
import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab } from "react-bootstrap";
|
||||
import { Upload } from "react-bootstrap-icons";
|
||||
@@ -684,12 +685,10 @@ const CreateCustomer = () => {
|
||||
)}
|
||||
<div className="me-4 mb-3">
|
||||
<div className="field-label">Language Spoken</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={languageSpoken}
|
||||
onChange={setLanguageSpoken}
|
||||
options={LANGUAGE_OPTIONS}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., English, Mandarin"
|
||||
/>
|
||||
</div>
|
||||
@@ -820,12 +819,10 @@ const CreateCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Emergency Contact Role</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={contact.role}
|
||||
onChange={(value) => updateEmergencyContact(index, 'role', value)}
|
||||
options={EMERGENCY_CONTACT_ROLE_OPTIONS}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., Power of Attorney"
|
||||
/>
|
||||
</div>
|
||||
@@ -843,12 +840,10 @@ const CreateCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Days of Week</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={daysOfWeek}
|
||||
onChange={setDaysOfWeek}
|
||||
options={DAYS_OF_WEEK_OPTIONS}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., Mon, Wed, Fri"
|
||||
/>
|
||||
</div>
|
||||
@@ -937,12 +932,10 @@ const CreateCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Dietary Restrictions</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={dietaryRestrictions}
|
||||
onChange={setDietaryRestrictions}
|
||||
options={DIETARY_RESTRICTIONS_GROUPED}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., No Pork"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,8 @@ import {
|
||||
DIET_TEXTURE, DIET_TEXTURE_TEXT,
|
||||
TRANSPORTATION_TYPE, TRANSPORTATION_TYPE_TEXT,
|
||||
YES_NO, YES_NO_TEXT,
|
||||
PREFERRED_TEXT_LANGUAGE, PREFERRED_TEXT_LANGUAGE_TEXT
|
||||
PREFERRED_TEXT_LANGUAGE, PREFERRED_TEXT_LANGUAGE_TEXT,
|
||||
MultiSelectDropdown
|
||||
} from "../../shared";
|
||||
import { Upload, BoxArrowRight, CheckCircleFill } from "react-bootstrap-icons";
|
||||
|
||||
@@ -1018,12 +1019,10 @@ const UpdateCustomer = () => {
|
||||
)}
|
||||
<div className="me-4 mb-3">
|
||||
<div className="field-label">Language Spoken</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={languageSpoken}
|
||||
onChange={setLanguageSpoken}
|
||||
options={LANGUAGE_OPTIONS}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., English, Mandarin"
|
||||
/>
|
||||
</div>
|
||||
@@ -1154,12 +1153,10 @@ const UpdateCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Emergency Contact Role</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={contact.role}
|
||||
onChange={(value) => updateEmergencyContact(index, 'role', value)}
|
||||
options={EMERGENCY_CONTACT_ROLE_OPTIONS}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., Power of Attorney"
|
||||
/>
|
||||
</div>
|
||||
@@ -1177,12 +1174,10 @@ const UpdateCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Days of Week</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={daysOfWeek}
|
||||
onChange={setDaysOfWeek}
|
||||
options={DAYS_OF_WEEK_OPTIONS}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., Mon, Wed, Fri"
|
||||
/>
|
||||
</div>
|
||||
@@ -1286,12 +1281,10 @@ const UpdateCustomer = () => {
|
||||
<div className="app-main-content-fields-section">
|
||||
<div className="me-4">
|
||||
<div className="field-label">Dietary Restrictions</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={dietaryRestrictions}
|
||||
onChange={setDietaryRestrictions}
|
||||
options={DIETARY_RESTRICTIONS_GROUPED}
|
||||
styles={multiSelectStyles}
|
||||
placeholder="e.g., No Pork"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { AuthService, MessageService, CustomerService } from "../../services";
|
||||
import { Breadcrumb, Tabs, Tab, Modal, Button, Dropdown } from "react-bootstrap";
|
||||
import { PencilSquare, Plus, Trash, Send, Eye, ArrowLeft, Filter, Calendar3, Search, ChevronLeft, ChevronRight } from "react-bootstrap-icons";
|
||||
import Select from 'react-select';
|
||||
import { MultiSelectDropdown } from '../../shared';
|
||||
import DatePicker from 'react-datepicker';
|
||||
import moment from 'moment';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
@@ -520,22 +521,11 @@ const MessageList = () => {
|
||||
<Modal.Body>
|
||||
<div className="mb-3">
|
||||
<label className="form-label"><strong>Select Recipient</strong> <span className="text-danger">*</span></label>
|
||||
<div className="d-flex align-items-center mb-2">
|
||||
<button className="btn btn-outline-secondary btn-sm" onClick={handleSelectAll}>
|
||||
{selectedRecipients.length === eligibleCustomers.length ? 'Deselect All' : 'Select All'}
|
||||
</button>
|
||||
<span className="ms-2 text-muted" style={{ fontSize: '13px' }}>{selectedRecipients.length} selected</span>
|
||||
</div>
|
||||
<Select
|
||||
isMulti
|
||||
<MultiSelectDropdown
|
||||
value={selectedRecipients}
|
||||
onChange={(val) => setSelectedRecipients(val || [])}
|
||||
options={eligibleCustomers.map(c => ({ value: c.id, label: c.name }))}
|
||||
placeholder="e.g., Recipient Name"
|
||||
styles={{
|
||||
control: (base) => ({ ...base, borderRadius: '8px' }),
|
||||
indicatorSeparator: () => ({ display: 'none' })
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
|
||||
145
client/src/shared/components/MultiSelectDropdown.js
Normal file
145
client/src/shared/components/MultiSelectDropdown.js
Normal file
@@ -0,0 +1,145 @@
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
|
||||
const MultiSelectDropdown = ({
|
||||
value = [],
|
||||
onChange,
|
||||
options = [],
|
||||
placeholder = 'Select...',
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [search, setSearch] = useState('');
|
||||
const containerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e) => {
|
||||
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
||||
setIsOpen(false);
|
||||
setSearch('');
|
||||
}
|
||||
};
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, []);
|
||||
|
||||
// Flatten grouped options into a flat list for filtering/selection
|
||||
const flatOptions = options.reduce((acc, opt) => {
|
||||
if (opt.options) {
|
||||
return [...acc, ...opt.options];
|
||||
}
|
||||
return [...acc, opt];
|
||||
}, []);
|
||||
|
||||
const selectedValues = (value || []).map(v => v.value);
|
||||
|
||||
const filteredOptions = search
|
||||
? flatOptions.filter(opt => opt.label.toLowerCase().includes(search.toLowerCase()))
|
||||
: flatOptions;
|
||||
|
||||
const allFilteredSelected = filteredOptions.length > 0 && filteredOptions.every(opt => selectedValues.includes(opt.value));
|
||||
|
||||
const toggleOption = (opt) => {
|
||||
const exists = selectedValues.includes(opt.value);
|
||||
if (exists) {
|
||||
onChange(value.filter(v => v.value !== opt.value));
|
||||
} else {
|
||||
onChange([...value, opt]);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleSelectAll = () => {
|
||||
if (allFilteredSelected) {
|
||||
const filteredValues = filteredOptions.map(o => o.value);
|
||||
onChange(value.filter(v => !filteredValues.includes(v.value)));
|
||||
} else {
|
||||
const currentValues = new Set(selectedValues);
|
||||
const newItems = filteredOptions.filter(o => !currentValues.has(o.value));
|
||||
onChange([...value, ...newItems]);
|
||||
}
|
||||
};
|
||||
|
||||
const removeItem = (e, opt) => {
|
||||
e.stopPropagation();
|
||||
onChange(value.filter(v => v.value !== opt.value));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="multi-select-dropdown" ref={containerRef}>
|
||||
<div
|
||||
className={`multi-select-dropdown__control ${isOpen ? 'multi-select-dropdown__control--open' : ''}`}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
>
|
||||
<div className="multi-select-dropdown__value-container">
|
||||
{value.length === 0 ? (
|
||||
<span className="multi-select-dropdown__placeholder">{placeholder}</span>
|
||||
) : (
|
||||
<div className="multi-select-dropdown__tags">
|
||||
{value.map((v) => (
|
||||
<span key={v.value} className="multi-select-dropdown__tag">
|
||||
{v.label}
|
||||
<span className="multi-select-dropdown__tag-remove" onClick={(e) => removeItem(e, v)}>×</span>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="multi-select-dropdown__indicator">
|
||||
<svg width="16" height="16" viewBox="0 0 20 20" style={{ transform: isOpen ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' }}>
|
||||
<path d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z" fill="#999" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isOpen && (
|
||||
<div className="multi-select-dropdown__menu">
|
||||
<div className="multi-select-dropdown__search-container">
|
||||
<input
|
||||
type="text"
|
||||
className="multi-select-dropdown__search"
|
||||
placeholder="Search..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="multi-select-dropdown__option multi-select-dropdown__select-all"
|
||||
onClick={toggleSelectAll}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={allFilteredSelected}
|
||||
onChange={toggleSelectAll}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="multi-select-dropdown__checkbox"
|
||||
/>
|
||||
<span>Select All</span>
|
||||
</div>
|
||||
<div className="multi-select-dropdown__options-list">
|
||||
{filteredOptions.length === 0 && (
|
||||
<div className="multi-select-dropdown__no-options">No options found</div>
|
||||
)}
|
||||
{filteredOptions.map((opt) => (
|
||||
<div
|
||||
key={opt.value}
|
||||
className={`multi-select-dropdown__option ${selectedValues.includes(opt.value) ? 'multi-select-dropdown__option--selected' : ''}`}
|
||||
onClick={() => toggleOption(opt)}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedValues.includes(opt.value)}
|
||||
onChange={() => toggleOption(opt)}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="multi-select-dropdown__checkbox"
|
||||
/>
|
||||
<span>{opt.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MultiSelectDropdown;
|
||||
@@ -1,2 +1,3 @@
|
||||
export { default as ManageTable } from './ManageTable';
|
||||
export { default as Export } from './Export';
|
||||
export { default as Export } from './Export';
|
||||
export { default as MultiSelectDropdown } from './MultiSelectDropdown';
|
||||
Reference in New Issue
Block a user