Skip to content

Commit

Permalink
multiSelectLevel (from #1008)
Browse files Browse the repository at this point in the history
  • Loading branch information
sspenst committed Oct 4, 2023
1 parent 5bf2373 commit eb81176
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 36 deletions.
125 changes: 125 additions & 0 deletions components/page/multiSelectLevel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import Level from '@root/models/db/level';
import React, { useState } from 'react';
import AsyncSelect from 'react-select/async';
import { debounce } from 'throttle-debounce';

interface MultiSelectLevelProps {
controlStyles?: any;
defaultValue?: Level | null;
onSelect?: (selectedList: any, selectedItem: any) => void;
placeholder?: string
}

export default function MultiSelectLevel({ controlStyles, defaultValue, onSelect, placeholder }: MultiSelectLevelProps) {
const [options, setOptions] = useState([]);
const [value, setValue] = useState(defaultValue);

const doSearch = async (searchText: any, callback: any) => {
const search = encodeURI(searchText) || '';

const res = await fetch('/api/search?search=' + search, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
});

const data = await res.json();

setOptions(data?.levels);
callback(data?.levels);
};
const debounceDoSearch = debounce(500, doSearch);

return <AsyncSelect
backspaceRemovesValue={true}
className='text-left text-base'
components={{
DropdownIndicator: null,
IndicatorSeparator: null,
}}
formatOptionLabel={(option: any) => (
<>{option.name}</>
)}
getOptionLabel={(option: any) => option.name}
getOptionValue={(option: any) => option._id.toString()}
id='search-author-input-async-select'
instanceId='search-author-input-async-select'
isClearable={true}
loadOptions={debounceDoSearch}
noOptionsMessage={() => 'No levels found'}
onChange={(selectedOption: any, selectedAction: any) => {
setValue(selectedOption);

if (!selectedAction) {
return;
}

if (onSelect) {
if (selectedAction.action === 'clear') {
onSelect('', selectedAction);
} else {
onSelect(selectedOption, selectedAction);
}
}
}}
options={options} // Options to display in the dropdown
placeholder={placeholder ? placeholder : 'Search levels...'}
// https://react-select.com/styles
styles={{
control: (provided: any, state: any) => ({
...provided,
backgroundColor: 'white',
borderColor: state.isFocused ? 'rgb(37 99 235)' : 'rgb(209 213 219)',
borderRadius: '0.375rem',
borderWidth: '1px',
boxShadow: 'none',
cursor: 'text',
height: '2.5rem',
width: '13rem',
...controlStyles,
}),
dropdownIndicator: (provided: any) => ({
...provided,
color: 'black',
// change to search icon
'&:hover': {
color: 'gray',
},
}),
input: (provided: any) => ({
...provided,
color: 'rgb(55 65 81)',
}),
menu: (provided: any) => ({
...provided,
borderColor: 'rgb(209 213 219)',
borderRadius: '0.375rem',
borderWidth: '1px',
boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
marginTop: '2px',
}),
option: (provided: any, state: any) => ({
...provided,
backgroundColor: state.isSelected ? '#e2e8f0' : 'white',
color: 'black',
'&:hover': {
backgroundColor: '#e2e8f0',
},
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}),
placeholder: (provided: any) => ({
...provided,
color: 'rgb(156 163 175)',
}),
singleValue: (provided: any) => ({
...provided,
color: 'black',
}),
}}
value={value}
/>;
}
3 changes: 1 addition & 2 deletions models/schemas/levelSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export const LEVEL_SEARCH_DEFAULT_PROJECTION = { _id: 1, ts: 1, name: 1, slug: 1

const LevelSchema = new mongoose.Schema<Level>(
{

archivedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
Expand Down Expand Up @@ -114,7 +113,7 @@ const LevelSchema = new mongoose.Schema<Level>(
locale: 'en_US',
strength: 2,
},
}
},
);

LevelSchema.index({ slug: 1 }, { name: 'slug_index', unique: true });
Expand Down
Loading

0 comments on commit eb81176

Please sign in to comment.